How to make a bot delete messages after a certain time period - javascript

I'm trying to make my bot delete the 4 messages after 15 seconds, but I don't know how to make it do that.
const commando = require('discord.js-commando');
class HitOrMissCommand extends commando.Command
{
constructor(client)
{
super(client,{
name: 'hitormiss',
group: 'simple',
memberName: 'hitormiss',
description: 'i bet he doesnt kiss yah!'
});
}
async run(message, args)
{
message.reply("I guess they never miss, huh?")
message.reply("you got a boyfriend i bet he doesnt kiss yah!, MWAH!")
message.reply("He gon find another girl and he wont miss yah")
message.reply("He gon skirt and hit the dab like wiz khalifa")
}
}
module.exports = HitOrMissCommand;

if (message.content.startsWith(`!test`)) {
await message.channel.send('Hello').then(r => r.delete({ timeout: 5000 }))
console.log("test");
}

Might want to check out this question here.
As answered in that post the best way to do that is by deleting the message after x amount of seconds.
message.reply('Hit or miss.')
.then(msg => {
msg.delete(10000)
})
.catch(); /*Used for error handling*/
Proper credit should go to user LW001 who answered the question on the post I referred to.

Since this question is similar, you could use the same technique - adding a deletion timout. After you reply, .then() delete the message with your 15 second timer (15000 milliseconds):
message.reply("I guess they never miss, huh?").then(message => message.delete(15000)).catch(err => throw err);
Or if you can't use arrow syntax:
message.reply("I guess they never miss, huh?").then(function(message) {
message.delete(15000);
}).catch(function(err) {
throw err;
});

It could be done like this.
var replyM = message.reply("I guess they never miss, huh?")
setTimeout(function(){
replyM.delete
}, 1000);

Related

Automated github issue bot?

I would like to make a discord bot that creates an issue based on user input from discord. Any idea how I would do this? I am using JavaScript and would like to integrate it into an existing bot. Thanks!
You can take ideas from the LeagueSandbox/IssueBot (Typescript), which does create issues.
It does use npmjs.com/package/github-api, from github-tools/github
export class IssueCommand extends Command {
execute() {
if(!this.args) {
return
}
let issueBody = ISSUE_TEMPLATE
.replace("{PLACEHOLDER}", this.args[2] || "_No content_")
.replace("{CHANNEL}", this.message.channel.name)
.replace("{USER}", this.message.author.username)
Bot.gitHub.api.issues.create({
owner: config.githubName,
repo: this.args[0],
title: this.args[1],
body: <any>issueBody // Typings for the `github` package are incorrect, so we have to cast to any here.
},
(error, response) => this.handleGithubResponse(error, response)
)
}
handleGithubResponse(error, response) {
if(error) {
let formattedError = JSON.stringify(error, null, 4)
let reply = ERROR_TEMPLATE.replace('{PLACEHOLDER}', formattedError)
this.message.reply(reply)
return
}
let reply = SUCCESS_TEMPLATE.replace('{PLACEHOLDER}', response.html_url)
this.message.reply(reply)
}
}
You have to set up that bot in your Discord application.
Maybe see the GitHub API docs for Creating Issues
You might need to create an app for it.

Discord bot crashes when i try to add an image to embed with an if statement

I'm making a message logger, this is the code:
client.on('messageDelete', (messageDelete) => {
const deletedContent = `${messageDelete.content}`
const attachment = messageDelete.attachments.first()
const deletionEmbed = new Discord.MessageEmbed()
.setColor('RANDOM')
.setAuthor(`A message was deleted, content here:`)
.setDescription(deletedContent)
.addFields(
{ name: "Server:", value: `${messageDelete.guild.name}` },
{ name: "Channel:", value: `#${messageDelete.channel.name}` },
{ name: "Deleted by:", value: `${messageDelete.author.username}`},
)
.setTimestamp()
if (messageDelete.attachments.size !== 0) {
deletionEmbed.setImage(`${attachment.url}`)
}
client.channels.fetch("875333721492975646").then((channel) => {
channel.send(deletionEmbed).catch(err => {
console.log(err)
})
})
});
The line if (messageDelete.attachments.size !== 0) { deletionEmbed.setImage(attachment.url) } should add an image to the embed if there's any in the deleted message, and it does, but right after it crashes giving a RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values may not be empty. error, i don't why it happens, i already made different embeds that change based on situation and nothing went ever wrong. I also tried using a try/catch or console.error but they didn't resolve the problem and the bot kept crashing.
EDIT:
I've tried logging attachment.url and it does give the url, however when i click it it says this: <Error> <Code>AccessDenied</Code> <Message>Access denied.</Message> <Details> Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. </Details> </Error> Also attachment has an other property called "proxyURL" among with the normal url, i also tried using that one but still nothing, even if the link works correctly
You can always try the ? : way.
basically, we gonna check if there is an attachment, if yes then we gonna put the attachment url, else we will set the image as null so it doesn't even show.
Example:
const attachment = messageDelete.attachments.first()
const embed = new Discord.MessageEmbed()
.setTitle('test')
.setImage(attachment ? attachment.url : null)
If that didn't work, please console.log(attachment.url) and let me know what does it log, else if my method works, enjoy your day!

How to make the bot answer the user, when the bot responded and the user wanted to continue, like a conversation (but without repeating)

Exemple:
user: "Hello!" - bot: "Hi! You wanna help with the codes?"
user: "No" - bot: "Okay!"
But but it happens only when user says hello. I don't want him responds "Okay!" when a user say "No" in any sentences... the code then I use to the bot reply the user is:
client.on('message', async message => {
if (message.content.toLowerCase().includes("hello")) {
message.channel.send("Hi! You wanna help with the codes?");
}
});
Sorry for my errors of english, I don't speak so much english...
Anyway, someone can help me?
ESPECIAL THANKS: https://stackoverflow.com/users/5896453/naszos
You can define a state for user and decide where to go next based on user's answer, for example(I assumed some kind of id on client object):
const userStates = {};
const replies = {
"": [
{
messages: ["hello"],
answer: "Hi! You wanna help with the codes?",
next_state: "asked_to_help",
},
],
asked_to_help: [
{
messages: ["no"],
answer: "Okay :(",
next_state: "",
},
{
messages: ["yes"],
answer: "Yay, tell me more!",
next_state: "some_next_stage",
},
],
};
client.on("message", async (message) => {
userStates[client.id] = userStates[client.id] || "";
const text = message.content.toLowerCase();
const possibleReplies = replies[userStates[client.id]].filter((reply) =>
reply.messages.includes(text)
); // filter by matching messages
const reply = possibleReplies [Math.floor(Math.random() * possibleReplies .length)]; // get random answer from valid ones
if (reply) {
message.channel.send(reply.answer);
userStates[client.id] = reply.next_state;
} else {
message.channel.send("I dont understand :(");
}
});

Discord.js: Cannot Read Property "Name" of Null - How do I fix this?

I figured out how to make my Discord bot send an image to a certain channel whenever a specific user plays a specific game, but I have another problem.
When the application closes, I get this error saying, "Cannot read property 'name' of null." How do I fix this?
I haven't tried anything because I don't know anything about how I should use null.
// Game Detector \\
client.on("presenceUpdate", (oldMember, newMember) => {
if(newMember.id === '406742915352756235') {
if(newMember.presence.game.name === 'ROBLOX') { // New Example: ROBLOX
console.log('ROBLOX detected!');
client.channels.get('573671522116304901').send('**Joining Game:**', {
files: [
"https://cdn.discordapp.com/attachments/567519197052272692/579177282283896842/rblx1.png"
]
});
}
}
});
I expected the code to work, even when the application closes. Instead, it cannot read name of null. How can I fix this error?
This error is most likely thrown when the user stops playing a game, because newMember.presence.game will logically be null. Then, when you try to read name of newMember.presence.game, you receive your error.
Use this revised code:
client.on('presenceUpdate', (oldMember, newMember) => {
if (newMember.id !== '406742915352756235') return; // only check for this user
if (newMember.presence.game && newMember.presence.game.name === 'ROBLOX') {
console.log('ROBLOX detected.');
const channel = client.channels.get('573671522116304901');
if (!channel) return console.log('Unable to find channel.');
channel.send('**Joining Game:**', {
files: ['https://cdn.discordapp.com/attachments/567519197052272692/579177282283896842/rblx1.png']
}).catch(console.error);
}
});

How to write my code to test a websocket event?

I am trying to test that data gets added to my database after a websocket event has fired.
In the application I am working with there is already a working example of this.
it('some test name', function (done) {
this.timeout(12000)
var socket = io.connect('http://localhost:3000', {
'transports': [
'websocket',
'flashsocket',
'jsonp-polling',
'xhr-polling',
'htmlfile'
]
})
socket.emit('some-room-event', {
participant: 'p1',
room: 12,
active: true
})
setTimeout(function () {
app.service('rooms').get(12)
.then(function (room) {
assert(room.active === true)
socket.disconnect()
done()
}).catch(function (err) {
socket.disconnect()
done(err)
})
}, 11000)
})
I am coming from a ruby background and slotting into the project so I am quite new. It feels a bit like the use of a timeout is a code smell and it just feels wrong. You don't want to increase the duration it takes to run your tests by an arbitrary wait time.
I have read a lot of articles around this, but it's pretty confusing. Is there a better way to structure this code and potentially get rid of the setTimeout?
I am using feathersjs, mocha and assert.
It looks like the event that is being tested is just a normal websocket event that does something to the rooms service.
An arbitrary timeout in the test is definitely not the best way to solve the issue that the websocket event does not acknowledge when it has completed whatever it was supposed to do. What I think you could do is to listen to a Feathers service event when the room is updated or patched (although it is a little odd that the socket event isn't just using the official socket.emit('rooms::update', data) to update the room state):
it('some test name', function (done) {
var socket = io.connect('http://localhost:3000', {
'transports': [
'websocket',
'flashsocket',
'jsonp-polling',
'xhr-polling',
'htmlfile'
]
});
app.service('rooms').once('updated', function(room) {
assert(room.active);
done();
});
socket.emit('some-room-event', {
participant: 'p1',
room: 12,
active: true
});
});

Categories

Resources