Tech With Tim Logo
Go back

Logging and Storing Information

Logging

For a discord server of any size logging is an important feature. Especially for large discord servers with multiple staff members and many different channels. We can choose to log information such as deleted and edited messages, kicks, bans, member joins, number of messages sent and much more.

For this tutorial I will be setting up a log to keep track of the number of new users and messages sent each day.

Importing Modules

We will need to important the following two modules before beginning.

import time
import asyncio

Timing Events

We want to set up a timer so that we update our text file every x seconds, or minutes. Sometimes It doesn't make sense to write information every second, for example if we have a small server where only a few messages are sent a day. To do this we are first going to write the function that we will call every x seconds. We will also create two global variables which will keep track of the amount of new messages and users.

joined = 0
messages = 0

async def update_stats():
    await client.wait_until_ready()
    global messages, joined

To have the function run constantly in the background we add the following code to the end of our script.

client.loop.create_task(update_stats())

Incrementing Messages and Joined

Now whenever a new member joins or a message is sent we will increment the global variables we created.

We need to modify the functions below and add the highlighted lines.

@client.event
async def on_message(message):
    global messages # ADD TO TOP OF THIS FUNCTION
    messages += 1 # ADD TO TOP OF THIS FUNCTION
    ...
@client.event
async def on_member_join(member):
    global joined # ADD TO TOP OF THIS FUNCTION
    joined += 1 # ADD TO TOP OF THIS FUNCTION

Storing Data

We will now write the code for the update_stats() function. This function will use asyncio to delay the given amount of seconds before updating our log txt file.

IMPORTANT Please create a blank .txt file in the same directory as your script called, "stats.txt".

async def update_stats():
    await client.wait_until_ready()
    global messages, joined

    while not client.is_closed():
        try:
            with open("stats.txt", "a") as f:
                f.write(f"Time: {int(time.time())}, Messages: {messages}, Members Joined: {joined}\n")

            messages = 0
            joined = 0

            await asyncio.sleep(5)
        except Exception as e:
            print(e)
            await asyncio.sleep(5)

Now every 5 seconds our stats.txt file will be updated.

Full Code

import discord
import time
import asyncio

messages = joined = 0

def read_token():
    with open("token.txt", "r") as f:
        lines = f.readlines()
        return lines[0].strip()

token = read_token()

client = discord.Client()


async def update_stats():
    await client.wait_until_ready()
    global messages, joined

    while not client.is_closed():
        try:
            with open("stats.txt", "a") as f:
                f.write(f"Time: {int(time.time())}, Messages: {messages}, Members Joined: {joined}\n")

            messages = 0
            joined = 0

            await asyncio.sleep(5)
        except Exception as e:
            print(e)
            await asyncio.sleep(5)



@client.event
async def on_member_join(member):
    global joined
    joined += 1
    for channel in member.server.channels:
        if str(channel) == "general":
            await client.send_message(f"""Welcome to the server {member.mention}""")


@client.event
async def on_message(message):
    global messages
    messages += 1

    id = client.get_guild(ID HERE)
    channels = ["commands"]
    valid_users = ["Ti#9298"]

    if str(message.channel) in channels and str(message.author) in valid_users:
        if message.content.find("!hello") != -1:
            await message.channel.send("Hi") 
        elif message.content == "!users":
            await message.channel.send(f"""# of Members: {id.member_count}""")

client.loop.create_task(update_stats())
client.run(token)
Design & Development by Ibezio Logo