Discord.js "channel" not defined error message - javascript

I recently became interested in making a discord bot using Javascript and node.js. I am trying to make a command that spins a virtual "lottery", and sends a message telling the user whether they have received anything. (Here is my code:)
`
function lotteryCommand(arguments, receivedMessage){
/*note: receivedMessage is defined as the command (for my bot, it's e!spin)
and arguments is the part following the command (for this particular bit of code,
it's merits, so the user sends "e!spin merits")*/
if (arguments == "merits"){
setTimeout(randomlottery1, 1000);
}
else{receivedMessage.channel.send("Message here")}
}
here is the other function. This is where it stops working
function randomlottery1(arguments, receivedMessage){
let respond;
let responses = [
//some random phrases here
]
respond = responses[Math.floor(Math.random() * responses.length)]
receivedMessage.channel.send(respond)
}
For some reason I cannot understand, it does not recognize the channel in receivedMessage.channel.send the second time, in the randomlottery1 function, but it recognized the command earlier in the code. Is there anything I am doing wrong here? Thanks.

I think your problem is you are not passing in any parameters to your function, you can easily fix it by doing this:
function lotteryCommand(arguments, receivedMessage){
/*note: receivedMessage is defined as the command (for my bot, it's e!spin)
and arguments is the part following the command (for this particular bit of code,
it's merits, so the user sends "e!spin merits")*/
if (arguments == "merits"){
// dont forget to pass in the required parameters while executing your function (parameter1, parameter2)
setTimeout(randomlottery1(arguments, receivedMessage), 1000);
}
else{receivedMessage.channel.send("Message here")}
}

Related

Discord %sticky command

I'm currently trying to create a Discord bot that sends a message when a user with a specified role sends the command %sticky This is a test
I want it to always be the first message in the channel and every time another user types in the channel the bot deletes its last message and posts again. I haven't had any luck online yet even finding a bot that already does this functionality, or where to even start. Here's what I kind of have so far
var lastStickyMessage;
client.on('message', message => {
if (lastStickyMessage != null) {
message.channel.fetchMessage(lastStickyMessage)
.then(retrievedMessage => retrievedMessage.delete());
}
message.reply("This is a Sticky Message").then(sent => {
let lastStickyMessage = sent.id;
}
});
There are several errors with your variable management: One one hand you create a new let with the same name. Since a let is a scoped variable, the lastStickyMessage will have a different value inside the sent callback than it has outside of it, since those are two different variables (read more on this here).
Apart from that you should save the last sent ID in a file or somewhere since the var will be reset once you restart your bot (the built in fs module could help you with that, you can find the documentation here).
One last thing: If you initialize a variable without a value it is not null but undefined. If you only check using == it will still evaluate to true (means null == undefined) but if you compare using ===, it will evaluate to false (null !== undefined). In your case this is not really a problem but this might be good to know for other cases.

Discord Bot Development: How do I stop this infinite loop?

This calls and retrieves a dog url from random.dog, when posting the link to log it stops at one, however when using message.channel.send below it runs an infinite loop of the call, what would be the best way to prevent this and to only send one link then stop till it is called again?
const animals = require('relevant-animals')
client.on("message", (message) => {
if(message.content.includes("dog")){
animals.dog().then(s => message.channel.send(s)) ;
animals.dog().then(s => console.log(s)) ;
};
Below is console log after one request it sends one link
Below is after it is sent to the channel, it just posts links non stop rather than just the one as shown in the console
Your bot is responding to itself. You can exclude it for replying to itself by using message.author.bot.
if(!message.author.bot) {
// Do something if message doesn't come from a bot.
}
I hope this code will help you getting on the right path, good luck!
You could just do this:
if(message.author.bot) return;
This wouldn't only stop bot from executing commands etc. on itself, it would prevent any bot from using your bot.
Since it checks for author of message if bot property returns true it would return;.
And if bot property returns false it would work as normally - only for users like you and me, and many others!
You can try this by doing the following code:
console.log(message.author.bot);
It will log the boolean value of bot property of the messages author.
You can read more about booleans (true/false) here.

Cannot access session state data on another function

I'm creating an inactivity check for my bot where it sends a message to the user if X amount of minutes have passed since the last message he sent.
bot.dialog('SomeDialog',
function(session, args){
let text = "The text sent to the user";
session.send(text, session.message.text);
check(session); //The function where I send the session to do the checking
session.endDialog();
}
);
The check function is where the problem happens:
check(session){
if(!session.conversationData.talked){
session.conversationData.talked = 1;
}
}
When I run it, I always get
Cannot read property 'conversationData' of undefined
If I use session.conversationData.talked within the bot.dialog it works, but not on the check function.
What am I doing wrong here?
Your code snippet works fine on my side, maybe you can provide your whole picture of your porject for further analysis.
However, to your requirememnt, you can consider to use the node package botbuilder-timeout,
This could be an "async" timing issue. The session on your browser / server needs to be sync'd.
Is this JS server side, or browser side? And what framework is this intended for?

How does the "client.on()" function really work?

I've been using Javascript to code discord bots lately, and most bots have a pretty standard program, something like this:
const Discord = require("discord.js");
const client = new Discord.Client();
client.on("message", (message) => {
//code to react to message
});
client.login("BOT-TOKEN");
Now, I'm not understanding how the client.on() works at a fundamental level. I'm able to understand that message in (message) represents the message object that's provided by discord to the client, but what does "message" stand for? It seems to be another parameter within the client.on() function, but what is that for? I've tried looking at the discord.js Documentation, but couldn't find the info about client.on().
That parameter is a string, showing what types of event to listen for.
Basically, when the Discord client receives a message, it will execute the function that is the second parameter. There are actually many other strings for different events. For example, if you use "ready" instead of message, it will call the function in the second parameter when the client is ready to start sending and receiving messages. You can see a list of these strings at their documentation: http://discordjs.readthedocs.io/en/latest/docs_client.html#events
on is used to add a callback function that's going to be executed when the event is triggered. for more refer this doc
https://nodejs.dev/en/learn/the-nodejs-event-emitter/

Understanding anonymous functions in Express js

I am new to express and am trying to wrap my head around callbacks in RESTful actions. In my PUT request below, I'm confused about the following line that I have bolded below. Why is response.pageInfo.book being set to the second parameter in the anonymous function (result)? that seems kind of arbitrary.
Also, what is the best way to inspect some of these parameters (req, res, result, etc)? When I console.log it, doesn't show up in my terminal or in my browser console.
exports.BookEdit = function(request, response) {
var id = request.params.id;
Model.BookModel.findOne({
_id: id
}, function(error, result) {
if (error) {
console.log("error");
response.redirect('/books?error=true&message=There was an error finding a book with this id');
} else {
response.pageInfo.title = "Edit Book";
**response.pageInfo.book = result;**
response.render('books/BookEdit', response.pageInfo)
}
})
}
The findOne function takes a query ({_id : id}) and a callback as arguments. The callback gets called after findOne has finished querying the database. This callback pattern is very common in nodejs. Typically the callback will have 2 arguments
the first one error is only set if there was an error.
the second one usually contains the value being returned. In this case you are finding one book in the database.
The line you have bolded is where the book object is assigned to a variable which will be sent back to be rendered in the browser. It is basically some javascript object.
Your second request, to debug this stuff, here is what you can do:
In you code type the word debugger;
e.g.
var id = request.params.id;
debugger;
Next, instead of running your program like this:
node myprogram.js
... run with debug flag, i.e.
node debug myprogram.js
It will pause at the beginning and you can continue by pressing c then Enter
Next it will stop at that debugger line above. Type repl and then Enter and you'll be able to inspect objects and variables by typing their names.
This works very well and requires no installation. However, you can also take a more visual approach and install a debugger such as node-inspector which does the same thing but in a web browser. If you use a good IDE (e.g. webstorm) you can also debug node.js pretty easily.
In the above, the document that is the result of the findOne() query is being added to the pageInfo key of the response and is then being rendered in a template. The first parameter is a potential error that must be checked and the remainder contain data. It's the standard node idiom that an asynchronous call returns to a callback where you do your work.
The writer of the code has also decided to decorate the response object with an extra attribute. This is often done when a request passes through a number of middleware functions and you might want to build up the response incrementally (for example having a middleware function that adds information about the current user to the pageInfo key).
Look and see what else is on response.pageInfo. Information was probably put there by previous middleware (especially since the function above expects the pageInfo key to exist). Just do a console.log(response.pageInfo) and look on your server log or standard out.

Categories

Resources