How can I create a Discord bot that reads and outputs specific text from a log file?

Hey everyone! I’m new to Python and I’m trying to develop a Discord bot that can monitor a constantly updating log file and output any line that contains the phrase ‘IMPORTANT:’. I am using Python 3.10.11 on Windows 10.

I’ve implemented a command using the @event.command decorator, but when I execute it, I encounter a TypeError that says ‘coroutine’ object is not iterable. Below is a revised version of my code that I came up with:

import discord
import os
from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.event
async def on_ready():
    print('Bot is online')

@bot.command()
async def check_log(ctx):
    log_path = os.path.join(os.getenv('APPDATA'), '.mylogs', 'updates.log')
    with open(log_path, 'r') as log_file:
        for line in log_file:
            if 'IMPORTANT:' in line:
                await ctx.send(line.strip())

bot.run('YOUR_TOKEN_HERE')

Whenever I trigger the command with !check_log, I get an error about a coroutine not being iterable. Can someone point out what might be wrong with this implementation?

hey mate, ur code looks alright but maybe try using asyncio.sleep() to check the file periodically? that way u can keep monitoring without blocking other bot functions. also, consider using a buffer to store recent lines so u dont resend stuff. good luck with ur project!

I’ve encountered a similar issue when working with Discord bots and log files. The problem likely stems from how you’re handling the file reading operation. Instead of reading the file line by line within the command, you might want to consider using an asynchronous approach.

Try modifying your check_log function to use aiofiles, which allows for asynchronous file operations:

import aiofiles

@bot.command()
async def check_log(ctx):
    log_path = os.path.join(os.getenv('APPDATA'), '.mylogs', 'updates.log')
    async with aiofiles.open(log_path, 'r') as log_file:
        content = await log_file.read()
        for line in content.split('\n'):
            if 'IMPORTANT:' in line:
                await ctx.send(line.strip())

Don’t forget to install aiofiles with pip install aiofiles. This should resolve the coroutine iteration error and make your bot more responsive when dealing with large log files.

I’ve dealt with similar challenges when creating Discord bots. One approach that worked well for me was implementing a background task to continuously monitor the log file. Here’s a rough idea of how you could do it:

import asyncio
from discord.ext import tasks

@tasks.loop(seconds=30)  # Adjust interval as needed
async def check_log_task():
    log_path = os.path.join(os.getenv('APPDATA'), '.mylogs', 'updates.log')
    with open(log_path, 'r') as log_file:
        log_file.seek(0, 2)  # Move to end of file
        while True:
            line = log_file.readline()
            if not line:
                await asyncio.sleep(0.1)  # Prevent CPU hogging
                continue
            if 'IMPORTANT:' in line:
                channel = bot.get_channel(YOUR_CHANNEL_ID)
                await channel.send(line.strip())

@bot.event
async def on_ready():
    check_log_task.start()

# Remove the @bot.command() function

This method continuously monitors the file without blocking other bot operations. Remember to replace YOUR_CHANNEL_ID with the actual channel ID where you want the bot to send messages. Hope this helps!