MongoDb with Discord bot
Tags: python, discord, bot, mongodb
Published: 2022-04-11 06:03:52

## A few commands to start

Creating a database for a bot is great if you are in need of tracking information for users that join your server for moderation.

A couple of things to do to start off with will be the loading of the extensions or "cogs" as they're known to a Python Discord bot.

```Python
import nextcord, os
...

for filename in os.listdir('./cogs'):

    # Ignore this file to prevent issues when connecting without having proper IP address access allowed
    if filename == 'MongoDB.py':
        pass
    elif filename.endswith('.py'):
        client.load_extension(f'cogs.{filename[:-3]}')
```

This will load all the cogs but skip loading the extension we'll create in order to prevent any issues due to not having the IP address set.

If you're like me and running different devices from different IPs then this WILL definitely be an issue unless you allow access from the IP you are trying to send requests to/from.

## Loading the MongoDB.py file

Using the `Bot.load_extension` method you'll be able to load this file (or any for the matter) when the command is sent.

```Python
...

@client.command()
@command.is_owner()
async def load(ctx, extension):
    try:
        client.load_extension(f'cogs.{extension}')
    except:
        await ctx.send(f'{extension} FAILED to load.', delete_after=5)
```

Conversely the `Bot.unload_extension` will do the opposite.

In the event you are working on any cog's file, you'll be able to call both the `unload` then `load` commands and have current code for the bot.

```Python
...

@client.command()
@commands.is_owner()
asycn def reload(ctx, extension):
    try:
        await ctx.invoke(client.get_command("unload"), extension)
        await ctx.invoke(client.get_command("load"), extension)
    except:
        await ctx.send("Extension didn't reload properly")
```

## Setup MongoDB

A few things will be needed.

```Shell
python3 -m pip install pymongo
```

That will have install pymongo for our request.
Next head over to [MongoDB.com](https://www.mongodb.com/) and get an account created and setup a free account.

Once the deployment has finished has a database setup with a new collection in it.

The `username`, `password`, and `cluster name` will be needed in order to get connected to the server.

Set the password in a file that is being ignored by git to allow for dynamic changes if you need to change the password in the future.

```Python
from nextcord.ext import commands
from datetime import datetime
from pymongo import MongoClient

# Open file where the password is stored
with open('references/mongoDBpassword.txt', 'r') as f:
    password = f.read()

# Connect to the cluster
cluster = MongoClient(
    f"mongodb+srv://<USERNAME>:{password}@<CLUSTER_NAME>.nmmyy.mongodb.net/test")

db = cluster["<DATABASE_NAME"]

collection = db["COLLECTION_NAME"]


class MongoDB(commands.Cog):

    def __init__(self, client):
        self.client = client

    @commands.Cog.listener("on_message")
    async def theMessage(self, message):
        myquery = {"_id": message.author.id}
        username = message.author.name + "#" + message.author.discriminator

        # If a message is sent by a bot have it do nothing
        if message.author.bot:
            return

        # If a message is sent by a human do the things
        if not message.author.bot:

            # Message context
            await message.channel.send("We have got theMessage")
            print(
                f'\n---Message recieved---\n '
                f'guild name | guild channel | message author | message.author.display_name\n'
                f'{message.guild}: {message.channel} | {message.author} | {message.author.display_name} \n\n {message.content}\n\n  ---Message End--- \n\n'
            )
            if (collection.count_documents(myquery) == 0):
                if "python" in (message.content.lower()):
                    post = {
                        "username": username,
                        "_id": message.author.id,
                        "score": 1
                    }
                    collection.insert_one(post)

            else:
                if 'python' in (message.content.lower()):
                    query = myquery
                    user = collection.find(query)
                    for result in user:
                        score = result['score']
                    score = score + 1
                    collection.update_one(
                        myquery, {"$set": {"score": score}})
```

This is a simple request that will create a counter called `score` and begin applying that count anytime a user uses the word "python" in the message.

What this has also done is grabbed information about that user such as Discord username (with discriminator) which can be used to track users if they get put on a warning/ban list.

This can come in use in the event the admin want to unban an account or set the bot to only temporarily ban someone and release the ban (this info will be necessary).