From 03b6f00becd742ffe46287f7cd0fec9596b54171 Mon Sep 17 00:00:00 2001 From: mrfluffy Date: Tue, 16 Sep 2025 15:11:56 +0100 Subject: [PATCH] feat: added reply --- bot.py | 89 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/bot.py b/bot.py index 21cc457..fa71b22 100644 --- a/bot.py +++ b/bot.py @@ -3,52 +3,95 @@ from discord.ext import commands import re import os -# Set up intents explicitly intents = discord.Intents.default() -intents.message_content = True # Enable message content access +intents.message_content = True -# Set up the bot bot = commands.Bot(command_prefix='!', intents=intents) -# Event: Bot is ready and connected to Discord @bot.event async def on_ready(): print(f'Logged in as {bot.user.name}') -# Event: Triggered when a message is sent in a channel the bot can see +def replace_nixos(text: str) -> str: + # Replace "nixos" outside of URLs; preserve capitalization of the first letter + def repl(m): + if m.group(1): # a URL match -> keep as-is + return m.group(1) + word = m.group(2) + return 'FagOS' if word and word[0].isupper() else 'fagOS' + return re.sub(r'(https?://\S+)|(\bnixos\b)', repl, text, flags=re.IGNORECASE) + +async def build_reply_header(message: discord.Message) -> str: + """If message is a reply, return a header string with a jump link + short quote.""" + if not message.reference or not message.reference.message_id: + return "" + + # Try cached message first; otherwise fetch it + ref = message.reference.resolved + if ref is None: + try: + ref = await message.channel.fetch_message(message.reference.message_id) + except discord.NotFound: + return "" + except discord.Forbidden: + return "" + except discord.HTTPException: + return "" + + author = ref.author.display_name + jump = ref.jump_url + # Make a short one-line excerpt (content only; ignore embeds/attachments here) + excerpt = (ref.content or "").replace("\n", " ").strip() + if len(excerpt) > 120: + excerpt = excerpt[:117] + "..." + + # Blockquote style + jump link + header_lines = [f"> replying to [{author}]({jump})"] + if excerpt: + header_lines.append(f"> {excerpt}") + header = "\n".join(header_lines) + "\n\n" + return header + @bot.event -async def on_message(message): - # Ignore messages sent by the bot itself to prevent loops +async def on_message(message: discord.Message): if message.author == bot.user: return - # Replace "nixos" with "fagOS" (preserving case of the first letter), but exclude URLs starting with http(s):// - new_content = re.sub( - r'(https?://\S+)|(\bnixos\b)', - lambda m: m.group(1) if m.group(1) else ('FagOS' if m.group(2)[0].isupper() else 'fagOS'), - message.content, - flags=re.IGNORECASE - ) + new_content_body = replace_nixos(message.content) - # Only proceed if the content was actually modified - if new_content != message.content: - # Get or create a webhook for impersonation + # Only proceed if modified + if new_content_body != message.content: + # Build an emulated reply header if the message was a reply + reply_header = await build_reply_header(message) + new_content = reply_header + new_content_body + + # Get or create the webhook webhooks = await message.channel.webhooks() webhook = next((w for w in webhooks if w.name == 'FagOSWebhook'), None) if webhook is None: webhook = await message.channel.create_webhook(name='FagOSWebhook') - - await message.delete() # Delete the original - # Send the modified message via webhook with original user's username and avatar + # Delete the original message + try: + await message.delete() + except discord.Forbidden: + # If we can't delete, still continue with sending the replacement + pass + + # Send via webhook with the original display name & avatar + # Use wait=True so you get the created message back if you ever need it await webhook.send( content=new_content, username=message.author.display_name, - avatar_url=message.author.display_avatar.url + avatar_url=message.author.display_avatar.url, + wait=True, + allowed_mentions=discord.AllowedMentions( + everyone=False, roles=False, users=True, replied_user=False + ), + silent=False ) - # Allow other commands to process (if any) + # Let commands still work await bot.process_commands(message) -# Run the bot using the token from the environment variable bot.run(os.getenv('FAGOS_TOKEN')) \ No newline at end of file