discordbot/cogs/message_scraper_cog.py
2025-06-05 21:31:06 -06:00

72 lines
2.7 KiB
Python

import discord
from discord.ext import commands
import io
class MessageScraperCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name="scrape_messages")
@commands.is_owner()
async def scrape_messages(self, ctx, limit: int = 1000):
"""
Scrapes the last N messages from the current channel, excluding bots,
and includes reply information. Uploads the results as a .txt file.
"""
# The user wants exactly 'limit' messages, excluding bots and empty content.
# We need to fetch more than 'limit' and then filter.
# Set a reasonable max_fetch_limit to prevent excessive fetching in very sparse channels.
max_fetch_limit = (
limit * 5 if limit * 5 < 10000 else 10000
) # Fetch up to 5x the limit, or 1000, whichever is smaller
messages_data = []
fetched_count = 0
async for message in ctx.channel.history(limit=max_fetch_limit):
fetched_count += 1
if message.author.bot or not message.content:
continue
reply_info = ""
if message.reference and message.reference.message_id:
try:
replied_message = await ctx.channel.fetch_message(
message.reference.message_id
)
reply_info = f" (In reply to: '{replied_message.author.display_name}: {replied_message.content[:50]}...')"
except discord.NotFound:
reply_info = " (In reply to: [Original message not found])"
except discord.HTTPException:
reply_info = " (In reply to: [Could not fetch original message])"
messages_data.append(
f"[{message.created_at.strftime('%Y-%m-%d %H:%M:%S')}] "
f"{message.author.display_name} ({message.author.id}): "
f"{message.content}{reply_info}"
)
if len(messages_data) >= limit:
break
if not messages_data:
return await ctx.send("No valid messages found matching the criteria.")
# Trim messages_data to the requested limit if more were collected
messages_data = messages_data[:limit]
output_content = "\n".join(messages_data)
# Create a file-like object from the string content
file_data = io.BytesIO(output_content.encode("utf-8"))
# Send the file
await ctx.send(
f"Here are the last {len(messages_data)} messages from this channel (excluding bots):",
file=discord.File(file_data, filename="scraped_messages.txt"),
)
async def setup(bot):
await bot.add_cog(MessageScraperCog(bot))