feat: A.B.I.N.A.S.H Discord bot with GIF emotes, slash commands, and music

- Core bot with slash command tree (discord.py 2.7.x compatible)
- Commands: /ping, /info, /hello, /emoji, /app-emoji
- Admin: /upload-emoji, /list-emojis, /delete-emoji
- GIF emote detection and reaction handling
- Message reactions with percentage-based triggers and cooldowns
- Voice/music cog with YTDLSource, skip, volume, pause, resume, stop
- Global error handler and voice state change logging
- Environment config via .env (DISCORD_TOKEN, COMMAND_PREFIX, etc.)
This commit is contained in:
Benjamyn committed 2026-08-27 16:05:27 +10:00
commit 43ca943cb8
26 files changed
+1546

No files matched your search

View File
Whitespace-only changes.
+121
View File
@@ -0,0 +1,121 @@
"""Admin emoji management slash commands."""
import discord
from discord.app_commands import Command
from discord.ext import commands
async def upload_emoji(interaction: discord.Interaction, name: str, file_path: str) -> None:
"""Upload a custom emoji (JPG, PNG, or GIF) to the guild."""
if not interaction.guild:
await interaction.response.send_message(
"This command can only be used in a server.",
ephemeral=True,
)
return
if not interaction.guild.permissions_for(interaction.user).manage_emojis_and_stickers:
await interaction.response.send_message(
"You need manage_emojis_and_stickers permission.",
ephemeral=True,
)
return
try:
with open(file_path, "rb") as f:
image_bytes = f.read()
await interaction.guild.create_custom_emoji(name=name, image=image_bytes)
await interaction.response.send_message(
f"Successfully uploaded emoji `{name}`!",
ephemeral=True,
)
except FileNotFoundError:
await interaction.response.send_message(
"Error: File not found.",
ephemeral=True,
)
except Exception as e:
await interaction.response.send_message(
f"Error uploading emoji: {e}",
ephemeral=True,
)
upload_emoji.__signature__ = None # type: ignore
async def list_emojis(interaction: discord.Interaction) -> None:
"""List all custom emojis in the guild."""
if not interaction.guild:
await interaction.response.send_message(
"This command can only be used in a server.",
ephemeral=True,
)
return
emojis = await interaction.guild.emojis()
emoji_list = []
for emoji in emojis:
emoji_list.append(f"👍 `{emoji.name}` (ID: {emoji.id})")
if not emoji_list:
await interaction.response.send_message(
"No custom emojis found in this guild.",
ephemeral=True,
)
else:
await interaction.response.send_message("\n".join(emoji_list), ephemeral=True)
list_emojis.__signature__ = None # type: ignore
async def delete_emoji(interaction: discord.Interaction, *, name: str) -> None:
"""Delete a custom emoji."""
if not interaction.guild:
await interaction.response.send_message(
"This command can only be used in a server.",
ephemeral=True,
)
return
if not interaction.guild.permissions_for(interaction.user).manage_emojis_and_stickers:
await interaction.response.send_message(
"You need manage_emojis_and_stickers permission.",
ephemeral=True,
)
return
try:
emojis = await interaction.guild.emojis()
emoji = None
for e in emojis:
if e.name.lower() == name.lower():
emoji = e
break
if emoji is None:
await interaction.response.send_message(
f"Emoji `{name}` not found.",
ephemeral=True,
)
return
await emoji.delete()
await interaction.response.send_message(
f"Successfully deleted emoji `{name}`!",
ephemeral=True,
)
except discord.NotFound:
await interaction.response.send_message(
f"Emoji `{name}` not found.",
ephemeral=True,
)
except Exception as e:
await interaction.response.send_message(
f"Error deleting emoji: {e}",
ephemeral=True,
)
delete_emoji.__signature__ = None # type: ignore
+37
View File
@@ -0,0 +1,37 @@
"""Emoji slash commands."""
import discord
from discord.app_commands import Command
from discord.ext import commands
async def emoji(interaction: discord.Interaction, *, name: str) -> None:
"""Send a custom emoji by name (requires colon prefix)."""
emoji_str = f":{name}:"
await interaction.response.send_message(emoji_str, ephemeral=True)
emoji.__signature__ = None # type: ignore
async def app_emoji(interaction: discord.Interaction, *, emoji_id: int) -> None:
"""Fetch an application-owned emoji by ID."""
try:
emoji = await interaction.client.fetch_application_emoji(emoji_id)
await interaction.response.send_message(
f"Emoji: `{emoji.name}` — {emoji.url}",
ephemeral=True,
)
except discord.NotFound:
await interaction.response.send_message(
f"Emoji with ID {emoji_id} not found.",
ephemeral=True,
)
except discord.HTTPException as e:
await interaction.response.send_message(
f"Error fetching emoji: {e}",
ephemeral=True,
)
app_emoji.__signature__ = None # type: ignore
+16
View File
@@ -0,0 +1,16 @@
"""Hello slash command."""
import discord
from discord.app_commands import Command
from discord.ext import commands
async def hello(interaction: discord.Interaction, name: str = "World") -> None:
"""Greet a user by name."""
await interaction.response.send_message(
f"Hello, {name}!",
ephemeral=True,
)
hello.__signature__ = None # type: ignore
+30
View File
@@ -0,0 +1,30 @@
"""Ping slash command."""
import discord
from discord.app_commands import Command
from discord.ext import commands
async def ping(interaction: discord.Interaction) -> None:
"""Check the bot's latency."""
latency = round(interaction.client.latency * 1000)
await interaction.response.send_message(
f"Pong! Latency: {latency}ms",
ephemeral=True,
)
ping.__signature__ = None # type: ignore
async def info(interaction: discord.Interaction) -> None:
"""Show bot information."""
await interaction.response.send_message(
f"**{interaction.client.user.name}**\n"
f"ID: {interaction.client.user.id}\n"
f"Bot! (ping: {round(interaction.client.latency * 1000)}ms)",
ephemeral=True,
)
info.__signature__ = None # type: ignore