66 lines
2.7 KiB
Python
66 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))
|