As a Real Gamer...
Tags: opensource
Published: 2020-10-31 18:53:24

This week, keeping with tradition, I wanted to dip my nose into something new. This time, however, I wanted to at least keep in with the comfort of Javascript. I like the language and I'd like to have a versatile set of skills with it to match the versatility of the language itself. So this time I went about helping out with a 
Discord bot. 

![The Discord bot dashboard](https://dev-to-uploads.s3.amazonaws.com/i/7maqxhvy250i6q7tbbgd.png)

For the uninitiated, Discord is a Slack-like chatting platform that makes use of servers and channels. 

![Discord vs Slack sidebars](https://dev-to-uploads.s3.amazonaws.com/i/d31lcfolvolhx91m5elk.png)

A Discord bot is a programmable user in the server that will display certain information upon being issued commands. Not unlike any given command-line interface.

![Demonstration](https://dev-to-uploads.s3.amazonaws.com/i/b6uu6t0y9rumigqf8ovi.png)

The demonstration above betrays what the project I worked on was: a Discord bot for the game "MouseHunt".

{% github https://github.com/AardWolf/MHTimerBot %}

I won't go into too much detail on what the game entails (frankly I'm a little confused myself) but it seems to revolve around hunting mice that turn up in certain in-game locations on certain specific times of day and days of the week.

What this bot is meant to do is alert users in its own channel when a certain mouse has appeared in-game and allow users to query it for the last time a certain mouse was spotted.

The [issue](https://github.com/AardWolf/MHTimerBot/issues/215) in question is as follows:

1. The user attempts to query the bot for the locations of a mouse over the past 3 months

2. The bot spits out the location of the mouse _but only since the last 3 **days**_

3. Solution: we must change the code so that it will spit out the correct timeframe

This is a simple enough fix and I didn't expect it to be terribly difficult to replace a few lines of code. What the issue presented was an opportunity to learn about Discord bots! That was my goal.

## Setting up My Bot

![Creating a bot](https://dev-to-uploads.s3.amazonaws.com/i/p518ry8tihei78y8ux5m.png)

So, in order to test my changes, I need to set up a discord bot in a testing server so I can issue it commands. Obviously, the first step is making a bot.

After that, I simply need to grab the bot token and put it into my settings.json

###settings.json
```
{
 "token": "<token>",
 "bitly_token": "",
 "linkConversionChannel": "larrys-freebies",
 "timedAnnouncementChannels": {},
 "relic_hunter_webhook": "283571156236107777",
 "botPrefix": "-mh",
 "owner": "0",
 "reactions": {
  "success": "✅",
  "failure": "❌",
  "errorSequence": [
   "🤖",
   "💣",
   "💥"
  ]
 },
 "guilds": {
  "772109745703616524": {
   "timedAnnouncementChannels": [
    "timers"
   ],
   "linkConversionChannel": "larrys-freebies",
   "botPrefix": "-mh"
  }
 },
 "version": "1.00"
```

After that, I needed to invite the bot user into my server.  Discord makes this pretty easy since I can just generate a link to my bot and plug it into an invite to my server.

![Connect to Discord](https://dev-to-uploads.s3.amazonaws.com/i/ohyc2z65psol3dx44k0t.png)

Once the bot is in, I simply need to run ``npm install`` and ``node MHTimer.js`` and we're on our way!

![Bot works!](https://dev-to-uploads.s3.amazonaws.com/i/ww6yyjh2lm1n3wfov9tj.png)

![I can even get it chatting](https://dev-to-uploads.s3.amazonaws.com/i/bd3gkohok7gk0m8xiaiv.png)

If anyone else is interested in building a bot, I'd suggest referring to the very short [tutorial](https://discordpy.readthedocs.io/en/latest/discord.html) on discordpy.io.

## The Work

Next comes, of course, the actual coding. Like I said before, this wouldn't be completely difficult and will only require changing a few lines.

###original getFilter() function
```
function getFilter(tester) {
    // Process filter-y nicknames
    if (!tester)
        return;
    tester = `${tester}`;
    if (tester.startsWith('3'))
        tester = '3_days';
    else if (tester.startsWith('all'))
        tester = 'alltime';
    else if (tester === 'current') {
        tester = '1_month';
        for (const filter of filters) {
            if (filter.start_time && !filter.end_time && filter.code_name !== tester) {
                tester = filter.code_name;
                break;
            }
        }
    }
    return getSearchedEntity(tester, filters)[0];
}
```
As we can see above, when the user inputs anything with "3" at the beginning, the tester defaults to "3_days" and therefore only ever grabs the last 3 days (see explanation above). So what do we do? It's simple. Because we want to discern between 3 months and 3 days, we just change the if statement to pick.

###new getFilter() function snippet
```
if (tester.startsWith('3_d'))
        tester = '3_days';
    else if (tester.startsWith('3_m'))
        tester = '3_months';
```
With this simple change, we can give the bot 3 days and 3 months and get the correct output!

![It works!](https://dev-to-uploads.s3.amazonaws.com/i/edib8pjo811p5jud1opv.png)
 
 Great! Now that we're done changing the code, let's perform the [pull request](https://github.com/AardWolf/MHTimerBot/pull/216)

![Uh oh....](https://dev-to-uploads.s3.amazonaws.com/i/d3qv8nvhyfwruunke6sa.png)

Oh no! Looks like we missed something! Let's take a look at our tests.


###tests excerpts
```
suite.test('given string input - returns known shortcuts', t => {
        const inputs = [
            { input: '3', expected: '3_days' },
            { input: '3day', expected: '3_days' },
            { input: 'all', expected: 'alltime' },
            { input: 'allowance', expected: 'alltime' },
            { input: 'current', expected: '1_month' }, //NOTE this can only be asserted because we don't load the filter list
        ];
```
It looks like now that we changed the "3" = "3_days" in the above code snippet, the test doesn't work! This is unfortunate and will require a bit of change to the tests. Or maybe my commit will need to be changed to reflect that. Regardless I don't think I have bad code or anything. I think I'll wait to see what the repo maintainers have to say about it.

## The response

![Well... alright...](https://dev-to-uploads.s3.amazonaws.com/i/vtb4tyaee4obfy2s2fvj.png)
 
So it looks like we have a task! Let's update the testing files.

###the new test snippet
```
suite.test('given string input - returns known shortcuts', t => {
        const inputs = [
            { input: '3_d', expected: '3_days' },
            { input: '3days', expected: '3_days' },
            { input: '3_m', expected: '3_months' },
            { input: '3months', expected: '3_months' },
            { input: 'all', expected: 'alltime' },
            { input: 'allowance', expected: 'alltime' },
            { input: 'current', expected: '1_month' }, //NOTE this can only be asserted because we don't load the filter list
        ];
```

As you can see I just added in my new test conditions and off we go! This was all we had that was a problem so I'm pretty happy with this pull request.

![lgtm](https://dev-to-uploads.s3.amazonaws.com/i/ofg3pievt711p95ahdm4.png)
 
...and it looks like they are too. What a nice ending.

I should note a changed one more little thing in my code.

```
if (tester.startsWith('3_d') || tester.startsWith('3d'))
        tester = '3_days';
    else if (tester.startsWith('3_m') || tester.startsWith('3m'))
        tester = '3_months';
```
Just to add the condition of using '3days'/'3months' or '3d'/'3m' as an input because from what I saw before - it kinda seems like we want it there.

##Conclusion

So that's it! I learned how to set up a Discord bot and read through the code for this one to determine the best way to start on one which was my main goal with this issue. Not to mention, I edited some test code! Which I've never done before. I'm very happy with this week! I can't wait to apply this practice to a project of my own.