renesansz / discord-greeter-bot

My greeter bot for Discord
MIT License
49 stars 38 forks source link

I'd like to also add an feature to the bot to greet and say goodbye whenever someone joins or leaves, respectively, the channel(s)... #219

Closed DumbJoe closed 4 years ago

DumbJoe commented 5 years ago

How do I go about this?

Because the default tutorial only shows how to build a bot that only responds to the !ping command and that's it....

The tutorial should just be called "How to create a discord bot that only says pong when you say !ping on the text channel" Because it's not exactly a greeter bot I am accustomed to.....

If you could add this feature, then this tutorial would be more complete.....

pablo-gbr commented 5 years ago

Just add this into the bot

When someone enter the server:

client.on('guildMemberAdd', member => {
  defaultChannel.send(`Welcome ${member}.`);
});

When someone leaves the server:

client.on('guildMemberRemove', member => {
  defaultChannel.send(`Bye ${member}.`);
});
DumbJoe commented 5 years ago

Uuuuuhhhhhhh oh thanks...where do I add this?

pablo-gbr commented 5 years ago

Before the "client.on('message'..." code

DumbJoe commented 5 years ago

I don't have a "client.on('message'..." code, mine looks like this:

var Discord = require('discord.io');
var logger = require('winston');
var auth = require('./auth.json');
// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, {
    colorize: true
});
logger.level = 'debug';
// Initialize Discord Bot
var bot = new Discord.Client({
   token: auth.token,
   autorun: true
});
bot.on('ready', function (evt) {
    logger.info('Connected');
    logger.info('Logged in as: ');
    logger.info(bot.username + ' - (' + bot.id + ')');
});
bot.on('message', function (user, userID, channelID, message, evt) {
    // Our bot needs to know if it will execute a command
    // It will listen for messages that will start with `!`
    if (message.substring(0, 1) == '!' || message.substring(0, 13) == '@Noddy the Bot') { //looks at the first character of the string counting from left
        var args = message.substring(1).split(' ');
        var cmd = args[0];

        args = args.splice(1);
        switch(cmd) {
            // !ping
            case 'ping':
                bot.sendMessage({
                    to: channelID,
                    message: 'Pong!'
                });
            break;
            // Just add any case commands if you want to..
         }
     }
});

The only client reference I have is the line that reads: var bot = new Discord.Client({

pablo-gbr commented 5 years ago

Before your "bot.on('message'..." code then

DumbJoe commented 5 years ago

Before your "bot.on('message'..." code then

OH I see....hmmm thanks..

Oh I never noticed that he updated his site with the new 2019 tutorial: https://medium.com/davao-js/2019-tutorial-creating-your-first-simple-discord-bot-47fc836a170b and yeah I see what you meant by:

Before the "client.on('message'..." code

So I tried it with the new version build but when I created a test joiner bot and made him invite himself onto my server, no message from my greeter bot appeared and on the command prompt, I see:

C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:8
client.on('guildMemberAdd', member => {msg.defaultChannel.send(`Welcome ${member}.`);});
                                       ^

ReferenceError: msg is not defined
    at Client.client.on.member (C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:8:40)
    at Client.emit (events.js:193:13)
    at Guild._addMember (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\structures\Guild.js:1288:19)
    at GuildMemberAddHandler.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\packets\handlers\GuildMemberAdd.js:12:13)
    at WebSocketPacketManager.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:105:65)
    at WebSocketConnection.onPacket (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
    at WebSocketConnection.onMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
    at WebSocket.onMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\node_modules\ws\lib\event-target.js:120:16)
    at WebSocket.emit (events.js:193:13)
    at Receiver.receiverOnMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\node_modules\ws\lib\websocket.js:789:20)

Any ideas? This is the new code I got from them including your welcome and goodbye auto messages:

const Discord = require('discord.js');
const client = new Discord.Client();
const auth = require('./auth.json');

client.on('ready', () => {console.log(`Logged in as ${client.user.tag}!`);});

// When someone enter the server:
client.on('guildMemberAdd', member => {msg.defaultChannel.send(`Welcome ${member}.`);});

// When someone leaves the server:
client.on('guildMemberRemove', member => {msg.defaultChannel.send(`Bye ${member}.`);});

client.on('message', msg => {
    if (msg.content === 'ping') {
      msg.reply('pong');
    }
  });

client.login(auth.token);

When I try to login using the same method for the old version, I get:

C:\Users\Growlithe\Documents\For Discord Bot\Bot>node bot.js
C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\winston-transport\legacy.js:18
    throw new Error('Invalid transport, must be an object with a log method.');
    ^

Error: Invalid transport, must be an object with a log method.
    at new LegacyTransportStream (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\winston-transport\legacy.js:18:11)
    at DerivedLogger.add (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\winston\lib\winston\logger.js:345:11)
    at Object.winston.(anonymous function).args [as add] (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\winston\lib\winston.js:110:68)
    at Object.<anonymous> (C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:7:8)
    at Module._compile (internal/modules/cjs/loader.js:805:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:816:10)
    at Module.load (internal/modules/cjs/loader.js:672:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:612:12)
    at Function.Module._load (internal/modules/cjs/loader.js:604:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:868:12)

So looks like old version is broken from some discord update coz it used to work last I checked which was about two months ago....

pablo-gbr commented 5 years ago

Oh sorry, delete the 'msg.' part on both MemberAdd and MemberRemove, like this defaultChannel.send(`Welcome ${member}.`);

And for your 2nd issue, that's a winston issue, maybe this will fix it.

DumbJoe commented 5 years ago

OK now I get when someone leaves(or I kicked them since bots can't leave on their own accord):


C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:11
client.on('guildMemberRemove', member => {defaultChannel.send(`Bye ${member}.`);});
                                          ^

ReferenceError: defaultChannel is not defined
    at Client.client.on.member (C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:11:43)
    at Client.emit (events.js:193:13)
    at GuildMemberRemoveAction.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\actions\GuildMemberRemove.js:20:62)
    at GuildMemberRemoveHandler.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\packets\handlers\GuildMemberRemove.js:9:38)
    at WebSocketPacketManager.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:105:65)
    at WebSocketConnection.onPacket (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
    at WebSocketConnection.onMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
    at WebSocket.onMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\node_modules\ws\lib\event-target.js:120:16)
    at WebSocket.emit (events.js:193:13)
    at Receiver.receiverOnMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\node_modules\ws\lib\websocket.js:789:20)

And when my bot re-joins:


C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:8
client.on('guildMemberAdd', member => {defaultChannel.send(`Welcome ${member}.`);});
                                       ^

ReferenceError: defaultChannel is not defined
    at Client.client.on.member (C:\Users\Growlithe\Documents\For Discord Bot\Bot\bot.js:8:40)
    at Client.emit (events.js:193:13)
    at Guild._addMember (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\structures\Guild.js:1288:19)
    at GuildMemberAddHandler.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\packets\handlers\GuildMemberAdd.js:12:13)
    at WebSocketPacketManager.handle (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:105:65)
    at WebSocketConnection.onPacket (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
    at WebSocketConnection.onMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
    at WebSocket.onMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\node_modules\ws\lib\event-target.js:120:16)
    at WebSocket.emit (events.js:193:13)
    at Receiver.receiverOnMessage (C:\Users\Growlithe\Documents\For Discord Bot\Bot\node_modules\discord.js\node_modules\ws\lib\websocket.js:789:20)

I still get that same error after running npm install winston@2.4.0

DumbJoe commented 5 years ago

This is what my new code looks by the way as an update with your changes:

const Discord = require('discord.js');
const client = new Discord.Client();
const auth = require('./auth.json');

client.on('ready', () => {console.log(`Logged in as ${client.user.tag}!`);});

// When someone enter the server:
client.on('guildMemberAdd', member => {defaultChannel.send(`Welcome ${member}.`);});

// When someone leaves the server:
client.on('guildMemberRemove', member => {defaultChannel.send(`Bye ${member}.`);});

client.on('message', msg => {
    if (msg.content === 'ping') {
      msg.reply('pong');
    }
  });

client.login(auth.token);
pablo-gbr commented 5 years ago

Try this

client.on('guildMemberAdd', member => {
    const channel = member.guild.channels.find(ch => ch.name === 'general');
    if (!channel) return;
    channel.send(`Welcome ${member}!`);
});

client.on('guildMemberRemove', member => {
    const channel = member.guild.channels.find(ch => ch.name === 'general');
    if (!channel) return;
    channel.send(`Bye ${member}.`);
});

Replace 'general' with any channel you want. It should work.

DumbJoe commented 5 years ago

[gasps!]

It... works! Oh finally! Thankyou!!! Works!

Now....what should I add so that when I kick or ban someone, the bot says "X has been <kicked/banned> for "< reason >"." where X is the username that got kicked or banned, <kicked/banned> is kicked for when I kicked them and <kicked/banned> is banned when I banned them, and < reason > (apparently need to add spaces or else that entire word along with the <> disappears...) is whatever I typed in the reason box at the time of kicking/banning them?

Because we won't know if the user left on its own accord or was kicked/banned by a mod/admin of the discord group.

There might be one other thing after this, is there a way to change the date format from MM/DD/YY to DD/MM/YY on the time stamps? because in our local area, the time and date is read that TTTT DD/MM/YY and I've kinda grown accustomed to it so it now looks so out of place when it's formatted differently in discord....

And if I get all this done, that should be it and my discord group is ready for some action! hahaha

pablo-gbr commented 5 years ago

I don't think you can do that feature because, as far as I know, discord does not differenciate between kick/ban/leave when sending data over the api. You can do a !ban and !kick command if you want

And what do you mean by changing the time of the timestamps? Do you mean discord's timestamps?

DumbJoe commented 5 years ago

I don't think you can do that feature because, as far as I know, discord does not differenciate between kick/ban/leave when sending data over the api.

Oh I see....

You can do a !ban and !kick command if you want

As in be able to ban or kick someone as an alternative and the bot would spout out who kicked/banned who and why to the text channel?

And what do you mean by changing the time of the timestamps? Do you mean discord's timestamps?

Err, yeah I guess? Any way to change how discord formats the time stamp when comments are posted?

pablo-gbr commented 5 years ago

As in be able to ban or kick someone as an alternative and the bot would spout out who kicked/banned who and why to the text channel?

If you do a !ban command (for example: !ban 'user' 'reason') your bot can send a message to a channel like "User 'user' has been banned. Reason: 'reason'.". Same with !kick command.

Err, yeah I guess? Any way to change how discord formats the time stamp when comments are posted?

I don't think you can do this. Discord does not have any option to change timestamps.

DumbJoe commented 5 years ago

If you do a !ban command (for example: !ban 'user' 'reason') your bot can send a message to a channel like "User 'user' has been banned. Reason: 'reason'.". Same with !kick command.

I would have to manually add this to the bot.js file every time a user is banned or kicked and restart the server node, right? No way to automate this?

client.on('message', msg => {
    if (msg.content === 'ping') {
      msg.reply('pong');
    }
  });

Changing ping to !ban 'user' 'reason' in this case lets put my own name there so it now reads: !ban 'DumbJoe' 'reason' and if the bot has anything entires with DumbJoe in its reponds, for example: lets say pong to User 'DumbJoe' has been banned. Reason: 'Being a big baby!'. and that's how it would respond back? And if it doesn't have a response entry nothing happens? Or I should probably have a default message saying "This user is neither banned or kicked, yet....."

Or is it more sophisticated than this?

DumbJoe commented 5 years ago

I don't think you can do this. Discord does not have any option to change timestamps.

Awww....

pablo-gbr commented 5 years ago

I would have to manually add this to the bot.js file every time a user is banned or kicked and restart the server node, right? No way to automate this?

You don't need to restart the bot or manually add something in order to ban someone

Changing ping to !ban 'user' 'reason' in this case lets put my own name there so it now reads: !ban 'DumbJoe' 'reason' and if the bot has anything entires with DumbJoe in its reponds, for example: lets say pong to User 'DumbJoe' has been banned. Reason: 'Being a big baby!'. and that's how it would respond back? And if it doesn't have a response entry nothing happens? Or I should probably have a default message saying "This user is neither banned or kicked, yet....."

Or is it more sophisticated than this?

It's simpler than that. If you just do a command like this !ban user reason without mentioning the user, you'll have to search the user and that's not the way to do it.

Just do this (you'll have to check if the reason is empty (no reason) or if the user is empty, that's pretty easy):

if(msg.content.startsWith('!ban'){ //Syntax: !ban @username reason (you must mention the user you want to ban)
    var user = msg.mentions.members.first();
    var reason = msg.content.split(' ').splice(2).join(' ');
    user.ban(reason);
    msg.channel.send(`User ${user} has been banned. Reason: ${reason}.`);
}

Of course, you can improve the command system and everything. For example: using a switch statement for every command, check if a command starts with your prefix, only admins can use !ban, you can't ban admins, etc.

killrix commented 4 years ago

image node bot.js not getting the bot online what should I do image this is the bot.js

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.