feat: added reply
This commit is contained in:
89
bot.py
89
bot.py
@@ -3,52 +3,95 @@ from discord.ext import commands
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
# Set up intents explicitly
|
|
||||||
intents = discord.Intents.default()
|
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)
|
bot = commands.Bot(command_prefix='!', intents=intents)
|
||||||
|
|
||||||
# Event: Bot is ready and connected to Discord
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
print(f'Logged in as {bot.user.name}')
|
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
|
@bot.event
|
||||||
async def on_message(message):
|
async def on_message(message: discord.Message):
|
||||||
# Ignore messages sent by the bot itself to prevent loops
|
|
||||||
if message.author == bot.user:
|
if message.author == bot.user:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Replace "nixos" with "fagOS" (preserving case of the first letter), but exclude URLs starting with http(s)://
|
new_content_body = replace_nixos(message.content)
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
# Only proceed if the content was actually modified
|
# Only proceed if modified
|
||||||
if new_content != message.content:
|
if new_content_body != message.content:
|
||||||
# Get or create a webhook for impersonation
|
# 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()
|
webhooks = await message.channel.webhooks()
|
||||||
webhook = next((w for w in webhooks if w.name == 'FagOSWebhook'), None)
|
webhook = next((w for w in webhooks if w.name == 'FagOSWebhook'), None)
|
||||||
if webhook is None:
|
if webhook is None:
|
||||||
webhook = await message.channel.create_webhook(name='FagOSWebhook')
|
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(
|
await webhook.send(
|
||||||
content=new_content,
|
content=new_content,
|
||||||
username=message.author.display_name,
|
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)
|
await bot.process_commands(message)
|
||||||
|
|
||||||
# Run the bot using the token from the environment variable
|
|
||||||
bot.run(os.getenv('FAGOS_TOKEN'))
|
bot.run(os.getenv('FAGOS_TOKEN'))
|
||||||
Reference in New Issue
Block a user