I've been trying to add a cooldown to this part of my code for its too spammable to the point where I had to ban certain ppl from using it. So I've researched into cooldowns, trying different methods with no avail so I want to ask here if anyone has some hints or possible solutions to this. Thanks in advance.
const Telegraf = require('telegraf');
const Telegram = require('telegraf/telegram')
const bot = new Telegraf('******')
bot.hears(['oe', 'Oe', 'OE'], (ctx) => {
if (ctx.message.reply_to_message && ctx.message.reply_to_message.from.username != 'a username' && ctx.from.id != '****') { // Check if you're replying and if you're someone banned to use this command
var a = ctx.message.reply_to_message.from.username
ctx.reply('¿# este usuario?', {
reply_markup: {
inline_keyboard: [
[{ text: "Si", callback_data: "AD" }, { text: "Sin't", callback_data: "ADNT" }]
]
}
})
bot.action('AD', (ctx) => {
ctx.deleteMessage()
ctx.reply('#' + a + ' oe')
ctx.replyWithSticker('CAACAgEAAxkBAAOsX9WKywuspdVls5VSf9xV6ZLHrqAAAg8AA5390hUNDOUjryN26R4E')
})
bot.action('ADNT', (ctx) => {
ctx.deleteMessage()
})
} else {
console.log('No reply_to_message found! or the user is banned from doing this command')
}
})/**/ ```
Timestamps
Date.now will give you a timestamp in milliseconds. When the bot triggers, see if it has a timestamp. If it does, get a current timestamp and get the difference between timestamps. If it's under your threshold (say 5 seconds (5000ms)), skip replying. If it's over your threshold, update your saved timestamp with your current timestamp and have the bot reply.
Complete Guess
I'm not able to run the code and I'm not certain how it works, but my guess would be something along these lines
const Telegraf = require('telegraf');
const Telegram = require('telegraf/telegram')
const bot = new Telegraf('******')
let timestamp;
bot.hears(['oe', 'Oe', 'OE'], (ctx) => {
const rightNow = Date.now();
if(timestamp) {
// we have a timestamp from the last time we triggered
// so let's see if we've waited long enough...
const difference = rightNow - timestamp;
if(difference >= (5 * 1000) {
// enough time has elapsed, go ahead and do our thing
// but first, reset the timestamp for next time
timestamp = rightNow;
} else {
// nope, haven't waited long enough, abort, abort!
return;
}
} else {
// no timestamp available so this must be the first time
timestamp = rightNow;
}
if (ctx.message.reply_to_message && ctx.message.reply_to_message.from.username != 'a username' && ctx.from.id != '****') { // Check if you're replying and if you're someone banned to use this command
var a = ctx.message.reply_to_message.from.username
ctx.reply('¿# este usuario?', {
reply_markup: {
inline_keyboard: [
[{ text: "Si", callback_data: "AD" }, { text: "Sin't", callback_data: "ADNT" }]
]
}
})
bot.action('AD', (ctx) => {
ctx.deleteMessage()
ctx.reply('#' + a + ' oe')
ctx.replyWithSticker('CAACAgEAAxkBAAOsX9WKywuspdVls5VSf9xV6ZLHrqAAAg8AA5390hUNDOUjryN26R4E')
})
bot.action('ADNT', (ctx) => {
ctx.deleteMessage()
})
} else {
console.log('No reply_to_message found! or the user is banned from doing this command')
}
})/**/
Related
I am working on a discord image command that sends a random image every 10 seconds. When I start the command, it works. It starts sending images every 10 seconds, but when I try to make it stop, it just won't.
What went wrong? How can I fix this?
Image.js:
var Scraper = require('images-scraper');
const google = new Scraper({
puppeteer: {
headless: true,
},
});
var myinterval;
module.exports = {
name: 'image',
description: 'Sends profile pics)',
async execute(kaoru, message, args, Discord) {
//prefix "?"
const image_query = args.join(' ');
const image_results = await google.scrape(image_query, 100);
if (!image_query)
return message.channel.send('**Please enter name of the image!**');
if (image_query) {
message.delete();
myinterval = setInterval(function () {
message.channel.send(
image_results[Math.floor(Math.random() * (100 - 1)) + 1].url,
);
}, 10000);
} else if (message.content === '?stopp') {
clearInterval(myinterval);
message.reply('pinging successfully stopped!');
}
}
};
You can't just simply check the message.content inside the execute method. It will never be ?stopp as execute only called when you send the image command (i.e. ?image search term).
What you can do instead is to set up a new message collector in the same channel and check if the incoming message is your stop command. In my example below I used createMessageCollector. I've also added plenty of comments.
const google = new Scraper({
puppeteer: {
headless: true,
},
});
module.exports = {
name: 'image',
description: 'Sends profile pics',
async execute(kaoru, message, args, Discord) {
const query = args.join(' ');
if (!query)
return message.channel.send('**Please enter name of the image!**');
const results = await google.scrape(query, 100);
// also send error message if there are no results
if (!results?.length) return message.channel.send('**No image found!**');
// you probably want to send the first image right away
// and not after 10 seconds
const image = results[Math.floor(Math.random() * results.length)];
message.channel.send(image.url);
let intervalID = setInterval(() => {
// you don't need to add +1 and take away 1, it's unnecessary
// also, use results.length instead of the hardcoded 100
// as if there are no 100 results, it will throw an error
const image = results[Math.floor(Math.random() * results.length)];
message.channel.send(image.url);
}, 10000);
// use this filter to only collect message if...
const filter = (m) =>
// the author is the same as the user who executed the command
m.author.id === message.author.id &&
// and the message content is ?stopp
m.content.toLowerCase() === '?stopp';
// set up a message collector
const collector = message.channel.createMessageCollector({
// use the filter above
filter,
// you only need to collect a single message
max: 1,
});
// it fires when a message is collected
collector.on('collect', (collected) => {
clearInterval(intervalID);
// message.reply won't work as message is no longer available
message.channel.send('Pinging successfully stopped!');
});
message.delete();
}
};
My lock command is not working for some reason. It was working before and recently it has been annoying me. A terminal picture is below.
My code was working a month ago and now recently it has been acting up every time I add new code. I have compared my code from a month ago, only new code that I wrote was added.
const Discord = module.require("discord.js");
const fs =require("fs");
module.exports = {
name: "Timed Lockdown",
description: "Start a timed lockdown in a channel.",
run: async(client, message, args) => {
const time = args.join(" ");
if (!time) {
return message.channel.send("Enter a valid time period in `Seconds`, `Minutes` or `Hours`")
}
if (!message.member.hasPermission("MANAGE_SERVER", "MANAGE_CHANNELS")) {
return message.channel.send(`You don't have enough Permisions`)
}
message.channel.overwritePermissions([
{
id: message.guild.id,
deny : ['SEND_MESSAGES'],
},
],);
const embed = new Discord.MessageEmbed()
.setTitle("Channel Updates")
.setDescription(`${message.channel} has been locked for **${time}**`)
.setColor("RANDOM");
message.channel.send(embed)
let time1 = (`${time}`)
setTimeout(function(){
message.channel.overwritePermissions([
{
id: message.guild.id,
null: ['SEND_MESSAGES'],
},
],);
const embed2 = new Discord.MessageEmbed()
.setTitle("Channel Updates")
.setDescription(`Locked has been lifted in ${message.channel}`)
.setColor("RANDOM");
message.channel.send(embed2);
}, ms(time1));
message.delete();
}
}
You only have a run method in the object you're exporting from lock.js and you're calling execute in main.js.
You either need to update the method name in lock.js like this (and leave main.js as is:
module.exports = {
name: "Timed Lockdown",
description: "Start a timed lockdown in a channel.",
execute: async(client, message, args) => {
const time = args.join(" ");
// ... rest of code
Or call the run method in main.js like this:
if (command === "lock") {
client.commands.get("lock").run(message, args);
}
This is the current code that I have, I would like to make it where if you have a certain role then you can bypass the cooldown, also if anyone knows how to make a command that restricts a certain command to a certain channel, instead of having this really long message.channel.id.
const Discord = require('discord.js');
const fetch = require('node-fetch');
const talkedRecently = new Set();
module.exports.run = async(client, message, args, queue, searcher, ) => {
if (talkedRecently.has(message.author.id)) {
message.channel.send("Wait 1 minute before getting typing this again. " +'<#'+ message.author.id + '>');
} else {
switch(args[0].toLowerCase()){
case 'neko':
if(message.channel.id === '739002385531404288'||
message.channel.id === '646849145289834506'||
message.channel.id === '785079847763574794'||
message.channel.id === '782891383361896469'||
message.channel.id === '784417039425994772'){
fetch('https://nekos.life/api/v2/img/lewd')
.then(res => res.json())
.then(json => {
let nekoEmbed = new Discord.MessageEmbed()
.setTitle('Lewd Nekos! (=^・ω・^=)')
.setImage(json.url)
message.channel.send(nekoEmbed)
})
}else{
return}}
talkedRecently.add(message.author.id);
setTimeout(() => {
talkedRecently.delete(message.author.id);
}, 60000);
}
}
module.exports.config = {
name: "hentai",
aliases: ['ht']
}
```
Answering Your First Question:
Simply check if the member has a certain role. If they do, construct your if statement so that it will not fire if they have that role
Make sure to use message.member when checking roles
if (talkedRecently.has(message.author.id) && !message.member.roles.cache.has('bypass role id here')) {
// Your cooldown message
}
Learn more about Roles#has
Answering your 2nd question:
You can have an array of channel id's then use includes to check if any of the id's in the array match the current channel id
const ids = ['id1', 'id2', 'id3', 'id4'] // And so on
if (ids.includes(message.channel.id)) {
// Your Code
}
Learn more about Array.prototype.includes
So I've basically set up my suggestion bot, it's a very basis one but I'm looking to add a cool feature that will collect the positive and negative reactions and display a percentage. If the positive votes are more it would display 100%, if it's 1 positive and 1 negative it would display 50% and if it's negative it's 1 negative and nothing else it would display -100%. It's very simple but I'm struggling to understand how to do it. Any ideas?
For handle reaction you can use method createReactionCollector, but the 1 one problem is: method not triggered on reaction remove. So you need use some interval to check message reaction.
time: 120000 - its time to await reaction of millisecond, change it to whats you need.
If bot go restart hadling reactions will stop...
client.on('message', message => {
if (message.content.startsWith('test')) {
let suggestion = message.content.substring(0, 4) //test length
let embed = new Discord.MessageEmbed();
embed.setAuthor(message.author.tag, message.author.displayAvatarURL({
dynamic:true,
format: "png"
}))
embed.setTitle('Suggestion')
embed.setColor('GOLD')
embed.setDescription(suggestion)
embed.setTimestamp()
message.channel.send(embed).then(msg => {
msg.react('👍').then(() => msg.react('👎'))
const filter = (reaction, user) => {
return [`👍`, '👎'].includes(reaction.emoji.name)
};
let check = setInterval(handleReaction, 5000, message, msg, suggestion)
const collector = msg.createReactionCollector(filter, {
time: 120000,
});
collector.on('collect', (reaction, reactionCollector) => {
handleReaction(message, msg, suggestion)
});
collector.on('end', (reaction, reactionCollector) => {;
clearInterval(check)
});
})
}
})
function handleReaction (message, msg, suggestion) {
let embed = new Discord.MessageEmbed();
let positiveReaction = msg.reactions.cache.get('👍')
let negativeReaction = msg.reactions.cache.get('👎')
let negativeCount = negativeReaction ? negativeReaction.count : 0
let positiveCount = positiveReaction ? positiveReaction.count : 0
embed.setAuthor(message.author.tag, message.author.displayAvatarURL({
dynamic:true,
format: "png"
}))
embed.setTitle('Suggestion')
embed.setColor('GOLD')
embed.setDescription(suggestion)
embed.addField('Votes', `👍 - ${(positiveCount / (positiveCount + negativeCount) * 100).toFixed(2)}%\n👎 - ${(negativeCount / (positiveCount + negativeCount) * 100).toFixed(2)}%`)
embed.setTimestamp()
msg.edit(embed)
}
I Don't Really Now If This Is What You Were Looking For Directly But Here Is My Old Code From An Old Bot I Had
const sayMessage = args.join(" ");
if (!args.length) {
return message.channel.send(`You didn't provide any text! <:angry:713422454688710717>`);
}
const sentMessage = await client.channels.get(< CHANNEL ID HERE >).send({embed: {
color: 700000,
author: {
name: client.user.username,
},
title: "Suggestion",
description: sayMessage,
footer: {
timestamp: new Date(),
icon_url: client.user.avatarURL,
text: "Suggestion"
}
}});
message.react('👍');
sentMessage.react('👍').then(sentMessage.react('👎'))
message.channel.send("To vote for a suggestion, join my server. It should just be ..server!")
What It Does Is It Takes The Users Message And Puts It In An Embed And Reacts With Thumbs Up And Thumbs Down In The Channel Of Your Choice
But It May Need To Be Updated A Bit If Your Using V.12
I have created a discord bot recently using node js which when I do !purge, responds with Unknown command, do !help to view a list of command but after saying it, it is purging the messages. That is, it works well but posting that error message. I don't know what's the problem please help me
const commando = require('discord.js-commando');
const bot = new commando.Client();
const prefix = '!';
bot.on('message', message => {
let msg = message.content.toUpperCase();
let sender = message.author;
let cont = message.content.slice(prefix.length).split(" ");
let args = cont.slice(1);
if (msg.startsWith(prefix + 'PURGE')) {
async function purge() {
message.delete();
if (isNaN(args[0])) {
message.channel.send('Please input a number of messages to be deleted \n Syntax: ' + prefix + 'purge <amount>');
return;
}
const fetched = await message.channel.fetchMessages({limit: args[0]});
console.log(fetched.size + ' messages found, deleting...');
// Deleting the messages
message.channel.bulkDelete(fetched)
.catch(error => message.channel.send(`Error: ${error}`));
}
purge();
}
});
bot.login('MY BOT TOKEN HERE');
Right now you're using the discord.js-commando library. Any reason you decided to use that library? It looks like you're just using standard discord.js functions like bot.on, message.channel.send, message.channel.fetchMessages, message.channel.bulkDelete...
You should be good just useing the standard discord.js library, starting your code with this:
const Discord = require('discord.js');
const bot = new Discord.Client();
You can find this code on the main "Welcome" page of Discord.js
Edit:
I'm still not sure why you're using discord.js-commando, but that doesn't matter. Here's an example command I came up with using the discord.js-commando library:
const commando = require('discord.js-commando');
class PurgeCommand extends commando.Command {
constructor(client) {
super(client, {
name: 'purge',
group: 'random', // like your !roll command
memberName: 'purge',
description: 'Purge some messages from a Text Channel.',
examples: ['purge 5'],
args: [
{
key: 'numToPurge',
label: 'number',
prompt: 'Please input a number ( > 0) of messages to be deleted.',
type: 'integer'
}
]
});
}
run(msg, { numToPurge }) {
let channel = msg.channel;
// fail if number of messages to purge is invalid
if (numToPurge <= 0) {
return msg.reply('Purge number must be greater than 0');
}
// channel type must be text for .bulkDelete to be available
else if (channel.type === 'text') {
return channel.fetchMessages({limit: numToPurge})
.then(msgs => channel.bulkDelete(msgs))
.then(msgs => msg.reply(`Purge deleted ${msgs.size} message(s)`))
.catch(console.error);
}
else {
return msg.reply('Purge command only available in Text Channels');
}
}
};
module.exports = PurgeCommand
I'd also recommend using a new type instead of integer so you can validate the user's response and make sure they enter a number greater than 0.
If you need help setting up an initial discord.js-commando script, I'd take a look at this repo provided by the Discord team: https://github.com/discordjs/Commando/tree/master/test
You might wanna use this. This purge command is intended for discord.js v11.5.1 and I haven't tested to see if it works on v12, but I think this might work for you. I should say that THIS DELETES ALL THE CONTENT INSIDE THE CHANNEL (Nested command)
exports.run = (bot, message, args) => {
let filter = m => message.author.id === message.author.id;
message.channel.send("Are you sure you wanna delete all messages? (y/n)").then(() => {
message.channel.awaitMessages(filter, {
max: 1,
time: 30000,
errors: ['time']
})
.then(message => {
message = message.first();
if (message.content.toUpperCase() == "YES" || message.content.toUpperCase() == "Y") {
message.channel.bulkDelete(100);
} else if (message.content.toUpperCase() == "NO" || message.content.toUpperCase() == "N") {
message.channel.send("Terminated").then(() => {message.delete(2000)});
} else {
message.delete();
}
})
.catch(collected => {
message.channel.send("Timeout").then(() => {message.delete(2000)});
});
}).catch(error => {
message.channel.send(error);
});
};