import discord from discord.ext import commands import redditwarp.SYNC import json import os import aiohttp import asyncio # Load configuration config_path = os.path.join(os.path.dirname(__file__), "config.json") with open(config_path, "r") as f: config = json.load(f) bot_token = config.get("bot_token") prefix = config.get("prefix", ";") command_name = config.get("command_name", "rediddy") comment_limit = config.get("comment_limit", 2) delete_user_msg = config.get("delete_user_message_on_dismiss", True) uptime_kuma_url = config.get("uptime_kuma_url", "") uptime_kuma_interval = config.get("uptime_kuma_interval", 60) # Color mapping COLORS = { "blue": discord.Color.blue(), "green": discord.Color.green(), "red": discord.Color.red(), "gold": discord.Color.gold(), "purple": discord.Color.purple(), } sub_color = COLORS.get( config.get("embed_color_submission", "blue"), discord.Color.blue() ) comment_color = COLORS.get( config.get("embed_color_comments", "green"), discord.Color.green() ) # Setup Discord bot intents intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix=prefix, intents=intents) reddit_client = redditwarp.SYNC.Client() @bot.event async def on_ready(): print(f"Logged in as {bot.user} (ID: {bot.user.id})") print("------") if uptime_kuma_url: bot.loop.create_task(uptime_kuma_heartbeat()) async def uptime_kuma_heartbeat(): async with aiohttp.ClientSession() as session: while not bot.is_closed(): try: async with session.get(uptime_kuma_url) as resp: if resp.status == 200: print("Uptime Kuma heartbeat sent.") else: print(f"Uptime Kuma error: {resp.status}") except Exception as e: print(f"Uptime Kuma connection failed: {e}") await asyncio.sleep(uptime_kuma_interval) class RediddyView(discord.ui.View): def __init__(self, author_msg: discord.Message, submission_url: str): super().__init__(timeout=60) self.author_msg = author_msg self.add_item(discord.ui.Button(label="Open Submission", url=submission_url)) @discord.ui.button(label="Dismiss", style=discord.ButtonStyle.danger) async def dismiss( self, interaction: discord.Interaction, button: discord.ui.Button ): if delete_user_msg: try: await self.author_msg.delete() except discord.Forbidden: pass # May not have permission to delete user messages await interaction.message.delete() @bot.command(name=command_name) async def fetch_reddit_submission(ctx, subreddit_name: str, *, query: str): """Searches Reddit and returns the top post and comments in embeds.""" try: # Search for the subreddit name to get a valid subreddit object/ID sr_list = reddit_client.p.subreddit.search_names(subreddit_name) if not sr_list: await ctx.send(f"Subreddit '{subreddit_name}' not found.") return target_sr = sr_list[0] # Search for submissions within that subreddit submissions = reddit_client.p.submission.search(target_sr, query, 1, sort="top") found = False for submission_brief in submissions: found = True # Get full submission details submission = reddit_client.p.submission.get(submission_brief.id) title = submission.d.get("title", "Reddit Post") selftext = submission.d.get("selftext", "No content.") permalink = f"https://www.reddit.com{submission.d.get('permalink')}" # Submission Embed main_embed = discord.Embed( title=title, url=permalink, description=selftext[:2000] if selftext else "No content.", color=sub_color, ) main_embed.set_author(name=f"r/{target_sr}") embeds = [main_embed] # Fetch comments based on limit try: comment_tree = reddit_client.p.comment_tree.fetch( submission.id, limit=comment_limit, sort="top" ) for i, child in enumerate(comment_tree.children[:comment_limit]): comment_body = child.value.body comment_embed = discord.Embed( title=f"Top Comment #{i+1}", description=comment_body[:1000], color=comment_color, ) embeds.append(comment_embed) except Exception as e: print(f"Error fetching comments: {e}") view = RediddyView(ctx.message, permalink) await ctx.send(embeds=embeds, view=view) if not found: await ctx.send(f"No results found for '{query}' in {target_sr}.") except Exception as e: await ctx.send(f"An error occurred: {e}") bot.run(bot_token)