I want to create an if variable which checks if a user joins a certain channel, if they do then I'll keep doing my program.
What I have tried so far is different things like:
client.on('channel', async channel => {
if (channel.member.join(channel => channel.id === `672920107457970177`)) {
working.send("did it work??")
}
})
But I am pretty sure that my whole script is wrong; I only started using discord.js a few weeks ago.
You can use Client's voiceStateUpdate event. It will return 2 GuildMember values. The old one and the updated one.
Client.on("voiceStateUpdate", (oldMember, newMember) => {
if (!oldMember.voiceChannel && newMember.voiceChannel) {
console.log("oldMember channel doesn't exist. newMember channel exist. User joined a voice channel.")
} else if (!newMember.voiceChannel) {
console.log("newMember voice channel doesn't exist. User left a voice channel.")
}
})
You need to do these checks because voiceStatusUpdate is fired whenever the voice status updates (e.g. defean, mute, channel move etc.)
To check if the user joined a certain channel, just check the ID:
Client.on("voiceStateUpdate", (oldMember, newMember) => {
if (!oldMember.voiceChannel && newMember.voiceChannel && newMember.voiceChannelID == "CHANNEL ID") {
console.log(`User joined ${newMember.voiceChannel.name}!`)
}
})
Related
client.on("message", message =>{
if(message.channeltype = 'dm')
if (message.content === "confess")
message.channel.send("OOOOOOoooooo A SECRET??!?!?! WHAT IS IT?!??!")
message.channel.awaitMessages("response", message =>{
C = message.content
message.reply("Um.... theres two servers that this bot works on. 1: Loves in the snow or 2:🌙Moomins and Shep's Therapy Service🌙. Pick a number to send it to one of them")
client.on("message", message => { //////// SWITCH THIS LINE OUT FOR THE THING THAT WAITS FOR NEW MESSAGES
if (message.content === "2")
WDI = message.author
WDID = message.author.id
message.channel.get(WDIC2).send("Ok ok so who did it is" + WDI + "and their id is" + WDID)
message.channel.get(CC2).send(C)
if (message.content === "1")
WDI = message.author
WDID = message.author.id
message.channel.get(WDIC1).send("Ok ok so who did it is" + WDI + "and their id is" + WDID)
message.channel.get(CC1).send(C)
})
})})
Why does my bot not reply to my message?
I first put in confess then it would say the message but it doesnt detect that I continue and reply to that. WHat do I do?
Okay first off, try to be a lot more specific when asking questions there is a stackoverflow guide on how you should ask them effectively. Right now you are being unclear and I'm going to have to assume some stuff. Also, include a stack trace whenever possible, which there should have been as you provide some invalid properties, if you don't have one please include that there is not a stack trace in the question.
There is a lot of things wrong with this code. First off, the reason your bot isn't responding to you at all is because message.channeltype is not a property. Use message.channel.type instead. There is also something wrong with your message.channel.awaitMessages(). You are passing in a "response" string as a parameter, where there should be a filter. Since you don't need a filter since it is a dm channel you can just pass it in as null message.channel.awaitMessages(null, msg => { });. And awaitMessages is not the right call here. Await messages takes in messages in a certain time period, then resolving a promise with all of the collected messages. You should be using a discord.js collector. You should also not be using client.on("message") here. I'm assuming that you want to wait for messages in any channel after somebody "shared their secret". You can do that with a collector. If you want to collect messages all over the bot, or in just one discord server channel (using the filter which can be found on the docs) you can use a collector. This will wait for, in a number of milliseconds, for any event and filter out event triggers that aren't allowed. And when it gets it, it will run a lambda. Like this:
const filter = m => m.channel === message.channel && m.author = message.author); // The filter that will sort out the messages
const collector = message.channel.createMessageCollector(filter, { time: 30000 }); // creates a collector that will wait for 30 seconds
collector.on('collect', m => { // When somebody sends a message
// ...
if (message.content === '2') {
// ...
} else if (message.content === '1') {
// ...
} else {
message.reply('you need to say either 1 or 2. Please try again.');
return;
}
collector.stop(); // Makes sure that the collector no longer will receive anymore messages.
});
Final code (fill in the gaps I'm not going to code it all for you)
client.on("message", message => {
if(message.channel.type = 'dm')
if (message.content === "confess")
const filter = m => m.channel === message.channel && m.author = message.author; // The filter that will sort out the messages
const collector = message.channel.createMessageCollector(filter, {time: 30000})
collector.on('collect', message => {
const otherCollector = message.channel.createMessageCollector(filter, { time: 30000})
otherCollector.on('collect', message => {
if (message.content === '2') {
// ...
} else if (message.content === '1') {
// ...
} else {
message.reply('you need to say either 1 or 2. Please try again.');
return;
}
collector.stop(); // Makes sure that the collector no longer will receive anymore messages.
})
})
})
Also, before asking on any forum or discord server, always look up the documentation. It helps out 99% of cases, unless the docs is absolutely garbage.
Please read the docs. I'd say that the Discord.JS docs are a pretty handy reference.
For the first part, message.channeltype is not a real property, and do not use =. That is for setting variables, use == or === instead (What is the difference?). You can use message.channel.type or you can use instanceof as followed: message.channel instanceof Discord.DMChannel. Replace Discord with whatever your Discord.JS import variable is called.
Your ifs are missing some {}, they should be used as followed.:
if(message.channel instanceof Discord.DMChannel) {
//If the channel IS a DMChannel
} else return;
FYI, if you're planning to make multiple commands, I'd use a switch, and a way to convert message.content to arguments (string array).
message.channel.get is not a thing, use client.channels.cache.get. The variables C, and WDI / WDID need to have var before them.
Then you need to add a filter plus maximum messages, time limit, and minimum messages for your awaitMessages function. Plus you need then and catch, so now your code might look like this
if(message.channel instanceof Discord.DMChannel) {
if (message.content === "confess") {
message.channel.send("OOOOOOoooooo A SECRET??!?!?! WHAT IS IT?!??!")
message.reply("Um.... theres two servers that this bot works on. 1: Loves in the snow or 2:🌙Moomins and Shep's Therapy Service🌙. Pick a number to send it to one of them")
const filter = m => m.author == message.author;
message.channel.awaitMessages(filter, {/* whatever your parameters/limits are */})
.then(col => {
if (col.content === "2") {
/** Add in code */
} else if (col.content === "1") {
/** Add in code */
}
})
.catch(col => {/** Whatever you want to do if times up. */})
}
}
You may want to tweak the filter on this.
How to make a bot to ignore the same command after the bot joins a voice channel?
So if a user with permissions uses a command more than one time, the bot will just ignore the same commands because it has already joined the voice channel (the bot will ignore ?zipfm, but will not ignore others like ?disconnect or ?leave)
I tried making a cool down command, but still, if a user sends ?zipfm command more than one time bot starts to search dispatcher again after every command so we need to ignore that command after first time use.
client.on('message', async(message, user) =>{
if (message.content === '?zipfm'){
const role = message.guild.roles.cache.find((r) => r.name === 'ZIP FM 🎧🎶')
//--------------------------------------------------------------------------------------------------------
if (!role) return message.channel.send(`ZIP FM rolė nėra sukurta. Rašyk \`?sukurti\` norint sukurti ZIP FM rolę!`).then(msg => {
msg.delete({timeout:5000})
})
if (!message.member.roles.cache.has(role.id)) return message.channel.send(`Å i komanda yra leistina tik vartotojams turintiems ${role} rolÄ™.`).then(msg => {
msg.delete({timeout:5000})
})
if (message.channel.type == "dm") return;
if (message.member.voice.channel){
message.member.voice.channel.join().then(connection => {
connection.voice.setSelfDeaf(true);
message.channel.send("Paleidžiama ZIP FM 🎶").then(msg => {
msg.delete({timeout:10000})
})
const dispatcher = connection.play('https://transliacija.zipfm.lt/zipfm128.mp3',{filter: "audioonly"})
})
}
}
After checking if the message content is equal to ?zipfm, you can simply use the GuildMember#voice() function in order to determine whether or not the client is currently inside of a voice channel.
You can simply do that using:
if (message.guild.me.voice) return message.channel.send('I'm already inside of a voice channel!');
When I try
message.member.roles.add('695699359634817094');
I get the following error:
TypeError: Cannot read property 'add' of undefined
Is there a specific way to add my guild ID and update their role to that specific server through DM?
My function works within the guild by calling the command, however, through DM it doesn't.
You could do this by using message.author.id to get the user's ID and then using guild.get(guild_ID).members.fetch(user_ID) to access the GuildMember of that user.
You also mentioned that you give users the ability to run that command either in DM or a text channel in your guild.
If that is the case I would suggest adding a check to see if the command is being sent to a text channel or dm channel.
if (message.channel.type === "dm") {
const member = await client.guilds.get(guild_ID).members.fetch(message.author.id);
member.roles.add(role_ID);
} else {
message.member.roles.add('695699359634817094');
}
Ignore the if statement if you intend on having the command only run from dm.
By using the info given from Syntle and tipakA this is the solution.
if (message.channel.type === "dm") {
client.guilds.get('[SeverId]').members.fetch(message.author.id).then(async () => {
await client.guilds.get('[ServerId]').members.fetch(message.author.id).then((memberid) => {
memberid.roles.add('[roleid]');
}).catch((err) => {
console.log("ERROR");
});
});
}
else
{
message.member.roles.add('[roleid]');
}
I've got this so far:
function dailylot() {
let channel = message.guild.channels.find(channel => channel.name === "general69420")
if (!channel) {
return;
}
channel.send(".")
return;
}
function settimer() {
setTimeout(() => {
settimer()
dailylot()
console.log("Cycle")
}, 5000)
}
while (i < 1) {
console.log("set timer " + i);
settimer()
i++;
}
Doing this works but only for the guild the message is sent in. Even once removing the while loop so it activates multiple times, it just wants to go to 1 guild only. How can I retrieve the channels of all servers? bot.guilds.channels isn't a thing.
You wold need to iterate over each of the guilds in your bot and get the channels for each of tem, this is the case because different from message or guild, guilds is not a class, meaning it doesn't have properties like guilds.channels, it is a collection of other guild classes.
This is an example on how to access those channels individually:
client.guilds.forEach(guild => {
guild.channels.forEach(channel => {
// Use the channel for whatever you need
})
})
I need it so that a bot will send a message and if anyone on the server reacts to that message with a reaction it will give them a role.
I Have already tried multiple times, different code samples which allow reactions anywhere in the guild but i want it specific to one channel.
client.on("messageReactionAdd", (reaction, user) => {
if (user.bot) return;
const member = reaction.message.member
switch (reaction.name) {
case "😎":
member.addRole("597011179545690121").then((res) => {
reaction.message.channel.send(`You've been given the \`${res.name}\` role!`)
}).catch(console.error);
break;
case "🕵":
member.addRole("597011179545690121").then((res) => {
reaction.message.channel.send(`You've been given the \`${res.name}\` role!`)
}).catch(console.error);
};
})
client.on("messageReactionRemove", (reaction, user) => {
if (user.bot) return;
const member = reaction.message.member
switch (reaction.name) {
case "emoji_name_1":
member.removeRole("roleID").then((res) =>
reaction.message.channel.send(`You've been removed from the \`${res.name}\` role!`)
}).catch(console.error);
break;
case "emoji_name_2":
member.removeRole("someOtherRole").then((res) => {
reaction.message.channel.send(`You've been removed from the \`${res.name}\` role!`)
}).catch(console.error);
};
})
I Want the outcome to be that the person reacts with say a smiley face and they get a certain role but they have to react to a certain message sent by the bot in its own dedicated channel same as pre-made bots such as Reaction Roles bot.
First we have to fetch our Message.
let channel_id = "ChanelID of message";
let message_id = "ID of message";
client.on("ready", (reaction, user) => {
client.channels.get(channel_id).fetchMessage(message_id).then(m => {
console.log("Cached reaction message.");
}).catch(e => {
console.error("Error loading message.");
console.error(e);
});
Then we'll check if someone reacted to our message and give them the appropriate Role
client.on("messageReactionAdd", (reaction, user) => {
if(reaction.emoji.id == "EMOJI ID HERE" && reaction.message.id === message_id)
{
guild.fetchMember(user) // fetch the user that reacted
.then((member) =>
{
let role = (member.guild.roles.find(role => role.name === "YOUR ROLE NAME HERE"));
member.addRole(role)
.then(() =>
{
console.log(`Added the role to ${member.displayName}`);
}
);
});
}
}
I advise against using this code for multiple Roles at once as that would be rather inefficient.
const member = reaction.message.member
Problem: This is defining member as the GuildMember that sent the message, not the one that added the reaction.
Solution: Use the Guild.member() method, for example...
const member = reaction.message.guild.member(user);
switch (reaction.name) {...}
Problem: name is a not a valid property of a MessageReaction.
Solution: What you're looking for is ReactionEmoji.name, accessed via reaction.emoji.name.
...[the users] have to react to a certain message...
Problem: Your current code isn't checking anything about the message that's been reacted to. Therefore, it's triggered for any reaction.
Solution: Check the message ID to make sure it's the exact one you want. If you'd like to allow reactions on any message within a certain channel, check the message's channel ID.
Consider these examples:
if (reaction.message.id !== "insert message ID here") return;
if (reaction.message.channel.id !== "insert channel ID here") return;
Problem: The messageReactionAdd event is not emitted for reactions on uncached messages.
Solution: Use the raw event to fetch the required information and emit the event yourself, as shown here. Alternatively, use Caltrop's solution and fetch the message when the client is ready via TextChannel.fetchMessage().