diff --git a/bot.py b/bot.py deleted file mode 100644 index d2eafc8..0000000 --- a/bot.py +++ /dev/null @@ -1,153 +0,0 @@ -# discord_export_bot.py -# This bot connects to a Discord server and exports the entire message -# history from every accessible text channel into separate CSV files. - -# Make sure to install the discord.py library first: -# pip install discord.py - -import discord -import csv -import os -import asyncio - -# --- Configuration --- -# Place your Bot Token here. Treat this like a password! -# It's recommended to use environment variables for security. -BOT_TOKEN = "YOUR_BOT_TOKEN_HERE" - -# The directory where the CSV files will be saved. -# The script will create this directory if it doesn't exist. -OUTPUT_DIRECTORY = "discord_chat_logs" -# ------------------- - - -# --- Bot Setup --- -# Define the necessary "Intents" for the bot. Intents tell Discord what -# events your bot needs to receive. To read messages, we need the -# `messages` and `message_content` intents. You MUST enable these -# in the Discord Developer Portal for your bot. -intents = discord.Intents.default() -intents.guilds = True -intents.messages = True -intents.message_content = True # This is a privileged intent! - -# Create the bot client instance with the specified intents. -client = discord.Client(intents=intents) - -# --- Main Export Logic --- -async def export_channel_history(channel): - """ - Asynchronously fetches all messages from a given text channel - and saves them to a CSV file. - """ - print(f"Starting export for channel: #{channel.name} (ID: {channel.id})") - - # Sanitize channel name to create a valid filename - # Replaces invalid file name characters with an underscore - sanitized_channel_name = "".join(c if c.isalnum() else '_' for c in channel.name) - file_path = os.path.join(OUTPUT_DIRECTORY, f"{sanitized_channel_name}.csv") - - try: - message_count = 0 - with open(file_path, 'w', newline='', encoding='utf-8') as csvfile: - # Define the headers for the CSV file. This includes all the - # useful information we can easily get from a message object. - header = [ - 'message_id', 'timestamp_utc', 'author_id', 'author_name', - 'author_nickname', 'content', 'attachment_urls', 'embeds' - ] - writer = csv.DictWriter(csvfile, fieldnames=header) - writer.writeheader() - - # Fetch the channel's history. `limit=None` tells the library to - # fetch all messages. This can take a very long time and consume - # significant memory for channels with a large history. - async for message in channel.history(limit=None): - message_count += 1 - if message_count % 100 == 0: - print(f" ... processed {message_count} messages in #{channel.name}") - - # Extract attachment URLs - attachment_urls = ", ".join([att.url for att in message.attachments]) - - # Serialize embed objects to a string representation (e.g., JSON) - # This gives a detailed look into rich embeds. - embeds_str = ", ".join([str(embed.to_dict()) for embed in message.embeds]) - - # Write the message data as a row in the CSV - writer.writerow({ - 'message_id': message.id, - 'timestamp_utc': message.created_at, - 'author_id': message.author.id, - 'author_name': message.author.name, - 'author_nickname': message.author.nick, - 'content': message.content, - 'attachment_urls': attachment_urls, - 'embeds': embeds_str - }) - - print(f"✅ Finished exporting {message_count} messages from #{channel.name}.") - return True - - except discord.errors.Forbidden: - print(f"❌ ERROR: Permission denied for channel #{channel.name}. Skipping.") - return False - except Exception as e: - print(f"❌ An unexpected error occurred for channel #{channel.name}: {e}") - return False - -# --- Bot Events --- -@client.event -async def on_ready(): - """ - This event is triggered once the bot has successfully connected to Discord. - """ - print(f'Logged in as: {client.user.name} (ID: {client.user.id})') - print('------') - - # Create the output directory if it doesn't exist - if not os.path.exists(OUTPUT_DIRECTORY): - os.makedirs(OUTPUT_DIRECTORY) - print(f"Created output directory: {OUTPUT_DIRECTORY}") - - # Get the server (guild) the bot is in. This script assumes the bot - # is only in ONE server. If it's in multiple, you may need to specify - # which one to target. - guild = client.guilds[0] - if not guild: - print("Error: Bot does not appear to be in any server.") - await client.close() - return - - print(f"Targeting server: {guild.name} (ID: {guild.id})") - - # Get a list of all text channels the bot can see - text_channels = [channel for channel in guild.text_channels] - print(f"Found {len(text_channels)} text channels to export.") - - # Loop through each channel and run the export function - for channel in text_channels: - await export_channel_history(channel) - # A small delay to be respectful to Discord's API, although - # the library handles rate limiting automatically. - await asyncio.sleep(1) - - print('------') - print("All channels have been processed. The bot will now shut down.") - - # Shuts down the bot once the export is complete. - await client.close() - -# --- Run the Bot --- -if __name__ == "__main__": - if BOT_TOKEN == "YOUR_BOT_TOKEN_HERE": - print("!!! ERROR: Please replace 'YOUR_BOT_TOKEN_HERE' with your actual bot token in the script.") - else: - try: - # This starts the bot. The `on_ready` event will be called once it's connected. - client.run(BOT_TOKEN) - except discord.errors.LoginFailure: - print("!!! ERROR: Login failed. The token is likely invalid or incorrect.") - except Exception as e: - print(f"!!! An error occurred while running the bot: {e}") -