Search code examples
pythondiscorddiscord.pylogfile

Is it possible to make a Discord bot print out text from a .log file? (Received some errors)


I am trying to make a Discord bot print out certain text from a .log file with a @event.commanddecorator, but it shows errors. The Discord bot will only print out text when a row of text contains IMPORTANT:

also, the log file in this situation is constantly updating and adding text. I'm on Windows 10 with Python 3.10.11.

I've seen documentation on a bot reading certain text, and then logging it to a txt file, but none showing how to copy off from a .log file directly. and then printing it off to Discord. I was expected to see the bot spit out text that had IMPORTANT: in the rows of the log file. but as soon as I type ?run I only get errors, I am quite new to python, so I would love to see basic corrections on Syntax, and also the errors with the structure of the code,

Here are the errors I receive.

Traceback (most recent call last): File "C:\\Users\\\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\discord\\ext\\commands\\core.py", line 235, in wrapped ret = await coro(\*args, \*\*kwargs) File "C:\\Users\\*USER\\OneDrive\\Desktop\\DiscordBot\\main.py", line 18, in follow for line in loglines: TypeError: 'coroutine' object is not iterable

The above exception was the

direct cause of the following exception:

Traceback (most recent call last): File "C:\\Users\\*\*USER\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\discord\\ext\\commands\\bot.py", line 1366, in invoke await ctx.command.invoke(ctx) File "C:\\Users|\\\*USER\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\discord\\ext\\commands\\core.py", line 1029, in invoke await injected(\*ctx.args, \*\*ctx.kwargs) # type: ignore File "C:\\Users\\\*USER\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\discord\\ext\\commands\\core.py", line 244, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'coroutine' object is not iterable C:\\Users\\\*USER\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\events.py:80: RuntimeWarning: coroutine 'Command.\__call_\_' was never awaited self.\_context.run(self.\_callback, \*self.\_args) RuntimeWarning: Enable tracemalloc to get the object allocation traceback

Here is my code:

import discord
import time, os
from discord.ext import commands

@client.event
async def coroutine(ctx, *args): 
  print("Bot Is Ready")

@client.command()
async def run(thefile):
 if __name__ == "__main__":
    logfile = open(os.getenv("APPDATA")+"/.directory/logs/announcement.log", "r")
    loglines = follow(logfile)
    for line in loglines:
        if "IMPORTANT:" in line:
         await print (line)
        
client.run("token is here")

Solution

  • There are multiple errors in your code, which I will address below. However, we don't know what the follow method does, as it's not a built-in method and you didn't provide the code for it.

    Your main problem is that follow is a coroutine, but you didn't await it. Coroutines are asynchronous methods, such as ctx.send and guild.edit in discord.py - you have to put an await before calling that method.

    loglines = await follow(logfile)
    

    Now, about the other issues:

    • The on_ready function must be called on_ready for the library to recognize it, you called it coroutine
    • Bot.commands' first arguments will always be a 'commands.Context', usually named "ctx". You should update the method declaration: async def run(ctx: commands.Context): (we don't know what thefile is used for, if it's used at all)
    • if __name__ == "__main__": is usually not supposed to be in a command, but rather at the end of a file, and in this case, it should only contain client.run()
    • You didn't close logfile, it could cause a memory leakage. logfile.close()
    • Again, we don't know what follow() does, but you could probably replace it with logfile.readlines(), as this already returns a List[str] (a list containing strings), where every list item is a line from the file
    • print() is not a coroutine, and even though it does work even if you await it, it's weird and you'll get an error
    • Indentations are inconsistent, meaning on some lines, you used 3 spaces, while on another, you used 1, and then 2, and 4, etc. - indentations must consistently use the same amount of spaces for them to be recognized properly by the Python interpreter. Use the Tab key in any text editing software
    • PEP standards dictate that, when using mathematical operators such as +, you should put spaces around them to make the code easily sight-readable
    • PEP standards also dictate that you shouldn't put a space after calling a method: print ("Hello World") would look weird in comparison to print("Hello World")

    PEP standards are basically the "unwritten rules of Python", and PEP 8 is the one describing how one should format their code. It's not required for you to format your code in that exact way - you're completely free to put however many spaces you want after a method's name -, but it's generally more readable and prettier to format your code this way.