Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b9c797a
wip changes
meatsnails Jun 9, 2025
89691c3
Merge branch 'main' of https://github.com/cherryl1k/tux
meatsnails Jun 9, 2025
38c22a5
Merge branch 'allthingslinux:main' into main
meatsnails Jun 19, 2025
56bebaf
Added removing bookmarks from the bot's DMs
meatsnails Jun 19, 2025
217c364
fix(bookmarks): improve emoji validation and error handling for user …
electron271 Jun 19, 2025
b8a4072
added eletrons changes and fixed a warning
meatsnails Jun 19, 2025
f16d0f9
Merge branch 'main' of https://github.com/cherryl1k/tux
meatsnails Jun 19, 2025
34798e9
i think i fixed whatever the hell git just did
meatsnails Jun 19, 2025
e9119ab
Merge branch 'allthingslinux:main' into main
meatsnails Jun 19, 2025
72d3054
Merge branch 'allthingslinux:main' into main
meatsnails Jun 19, 2025
b547dd4
Merge branch 'main' of https://github.com/cherryl1k/tux
meatsnails Jun 20, 2025
0b4d6d9
Merge branch 'allthingslinux:main' into main
meatsnails Jun 20, 2025
ba2c381
chore(wip): still working on debugging
meatsnails Jun 20, 2025
1c5f20e
wip changes
meatsnails Jun 9, 2025
bdb6103
Added removing bookmarks from the bot's DMs
meatsnails Jun 19, 2025
66f4df9
added eletrons changes and fixed a warning
meatsnails Jun 19, 2025
b5dcbb7
fix(bookmarks): improve emoji validation and error handling for user …
electron271 Jun 19, 2025
2ce131a
chore(wip): still working on debugging
meatsnails Jun 20, 2025
5d36f15
Merge branch 'main' of https://github.com/cherryl1k/tux
meatsnails Jun 20, 2025
e0148cd
Merge branch 'main' of https://github.com/allthingslinux/tux
meatsnails Jun 21, 2025
61d1a22
feat:(bookmarks) cleaned up removing bookmarks
meatsnails Jun 21, 2025
67b53e2
Merge branch 'main' into main
kzndotsh Jun 21, 2025
e1d0024
feat(bookmarks): enhance bookmark functionality with improved error h…
kzndotsh Jun 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
287 changes: 221 additions & 66 deletions tux/cogs/services/bookmarks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from typing import cast
from __future__ import annotations

Check warning on line 1 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L1

Added line #L1 was not covered by tests

import io

Check warning on line 3 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L3

Added line #L3 was not covered by tests

import aiohttp

Check warning on line 5 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L5

Added line #L5 was not covered by tests
import discord
from discord.abc import Messageable

Check warning on line 7 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L7

Added line #L7 was not covered by tests
from discord.ext import commands
from loguru import logger

Expand All @@ -12,111 +16,262 @@
class Bookmarks(commands.Cog):
def __init__(self, bot: Tux) -> None:
self.bot = bot
self.add_bookmark_emojis = CONST.ADD_BOOKMARK
self.remove_bookmark_emojis = CONST.REMOVE_BOOKMARK
self.valid_emojis = self.add_bookmark_emojis + self.remove_bookmark_emojis
self.session = aiohttp.ClientSession()

Check warning on line 22 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L19-L22

Added lines #L19 - L22 were not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Instantiating aiohttp.ClientSession in init may cause warnings.

Move ClientSession creation to an async initialization method to prevent deprecation warnings and ensure compatibility with future aiohttp versions.

Suggested implementation:

        self.session = None
    async def cog_load(self) -> None:
        """Initializes resources for the cog, including the aiohttp session."""
        self.session = aiohttp.ClientSession()

    async def cog_unload(self) -> None:
        """Cleans up the cog, closing the aiohttp session."""
        if self.session:
            await self.session.close()


async def cog_unload(self) -> None:

Check warning on line 24 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L24

Added line #L24 was not covered by tests
"""Cleans up the cog, closing the aiohttp session."""
await self.session.close()

Check warning on line 26 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L26

Added line #L26 was not covered by tests

@commands.Cog.listener()
async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent) -> None:
"""
Handle the addition of a reaction to a message.
Handles bookmarking messages via reactions.
This listener checks for specific reaction emojis on messages and triggers
the bookmarking or unbookmarking process accordingly.
Parameters
----------
payload : discord.RawReactionActionEvent
The payload of the reaction event.
Returns
-------
None
The event payload containing information about the reaction.
"""

if str(payload.emoji) != "🔖":
# If the bot reacted to the message, or the user is the bot, or the emoji is not valid, return
if not self.bot.user or payload.user_id == self.bot.user.id or not payload.emoji.name:
return

# Fetch the channel where the reaction was added
channel = self.bot.get_channel(payload.channel_id)
if channel is None:
logger.error(f"Channel not found for ID: {payload.channel_id}")
# If the emoji is not valid, return
if payload.emoji.name not in self.valid_emojis:
return
channel = cast(discord.TextChannel | discord.Thread, channel)

# Fetch the message that was reacted to
try:
# Get the user who reacted to the message
user = self.bot.get_user(payload.user_id) or await self.bot.fetch_user(payload.user_id)

Check warning on line 52 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L52

Added line #L52 was not covered by tests

# Get the channel where the reaction was added
channel = self.bot.get_channel(payload.channel_id)

Check warning on line 55 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L55

Added line #L55 was not covered by tests
if channel is None:
channel = await self.bot.fetch_channel(payload.channel_id)

Check warning on line 57 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L57

Added line #L57 was not covered by tests

# If the channel is not messageable, return
if not isinstance(channel, Messageable):
logger.warning(f"Bookmark reaction in non-messageable channel {payload.channel_id}.")
return

Check warning on line 62 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L61-L62

Added lines #L61 - L62 were not covered by tests

# Get the message that was reacted to
message = await channel.fetch_message(payload.message_id)
except discord.NotFound:
logger.error(f"Message not found for ID: {payload.message_id}")
return
except (discord.Forbidden, discord.HTTPException) as fetch_error:
logger.error(f"Failed to fetch message: {fetch_error}")

# If the message is not found, return
except (discord.NotFound, discord.Forbidden, discord.HTTPException) as e:
logger.error(f"Failed to fetch data for bookmark event: {e}")

Check warning on line 69 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L68-L69

Added lines #L68 - L69 were not covered by tests
return

# Create an embed for the bookmarked message
# If the emoji is the add bookmark emoji, add the bookmark
if payload.emoji.name in self.add_bookmark_emojis:
await self.add_bookmark(user, message)

Check warning on line 74 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L74

Added line #L74 was not covered by tests

# If the emoji is the remove bookmark emoji, remove the bookmark
elif payload.emoji.name in self.remove_bookmark_emojis:
await self.remove_bookmark(message)

Check warning on line 78 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L78

Added line #L78 was not covered by tests

async def add_bookmark(self, user: discord.User, message: discord.Message) -> None:

Check warning on line 80 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L80

Added line #L80 was not covered by tests
"""
Sends a bookmarked message to the user's DMs.
Parameters
----------
user : discord.User
The user who bookmarked the message.
message : discord.Message
The message to be bookmarked.
"""
embed = self._create_bookmark_embed(message)
files = await self._get_files_from_message(message)

Check warning on line 92 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L92

Added line #L92 was not covered by tests

# Get the user who reacted to the message
user = self.bot.get_user(payload.user_id)
if user is None:
logger.error(f"User not found for ID: {payload.user_id}")
try:
dm_message = await user.send(embed=embed, files=files)
await dm_message.add_reaction(self.remove_bookmark_emojis)

Check warning on line 96 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L94-L96

Added lines #L94 - L96 were not covered by tests

except (discord.Forbidden, discord.HTTPException) as e:
logger.warning(f"Could not send DM to {user.name} ({user.id}): {e}")

Check warning on line 99 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L98-L99

Added lines #L98 - L99 were not covered by tests

try:
await message.channel.send(

Check warning on line 102 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L101-L102

Added lines #L101 - L102 were not covered by tests
f"{user.mention}, I couldn't send you a DM. Please check your privacy settings.",
delete_after=30,
)

except (discord.Forbidden, discord.HTTPException) as e2:
logger.error(f"Could not send notification in channel {message.channel.id}: {e2}")

Check warning on line 108 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L107-L108

Added lines #L107 - L108 were not covered by tests

@staticmethod
async def remove_bookmark(message: discord.Message) -> None:

Check warning on line 111 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L110-L111

Added lines #L110 - L111 were not covered by tests
"""
Deletes a bookmark DM when the user reacts with the remove emoji.
Parameters
----------
message : discord.Message
The bookmark message in the user's DMs to be deleted.
"""

try:
await message.delete()

Check warning on line 122 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L121-L122

Added lines #L121 - L122 were not covered by tests

except (discord.Forbidden, discord.HTTPException) as e:
logger.error(f"Failed to delete bookmark message {message.id}: {e}")

Check warning on line 125 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L124-L125

Added lines #L124 - L125 were not covered by tests

async def _get_files_from_attachments(self, message: discord.Message, files: list[discord.File]) -> None:

Check warning on line 127 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L127

Added line #L127 was not covered by tests
for attachment in message.attachments:
if len(files) >= 10:
break

Check warning on line 130 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L130

Added line #L130 was not covered by tests

if attachment.content_type and "image" in attachment.content_type:
try:
files.append(await attachment.to_file())
except (discord.HTTPException, discord.NotFound) as e:
logger.error(f"Failed to get attachment {attachment.filename}: {e}")

Check warning on line 136 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L133-L136

Added lines #L133 - L136 were not covered by tests

async def _get_files_from_stickers(self, message: discord.Message, files: list[discord.File]) -> None:

Check warning on line 138 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L138

Added line #L138 was not covered by tests
if len(files) >= 10:
return

# Send the bookmarked message to the user
await self._send_bookmark(user, message, embed, payload.emoji)
for sticker in message.stickers:
if len(files) >= 10:
break

Check warning on line 144 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L144

Added line #L144 was not covered by tests

def _create_bookmark_embed(
self,
message: discord.Message,
) -> discord.Embed:
if len(message.content) > CONST.EMBED_MAX_DESC_LENGTH:
message.content = f"{message.content[: CONST.EMBED_MAX_DESC_LENGTH - 3]}..."
if sticker.format in {discord.StickerFormatType.png, discord.StickerFormatType.apng}:
try:
sticker_bytes = await sticker.read()
files.append(discord.File(io.BytesIO(sticker_bytes), filename=f"{sticker.name}.png"))
except (discord.HTTPException, discord.NotFound) as e:
logger.error(f"Failed to read sticker {sticker.name}: {e}")

Check warning on line 151 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L147-L151

Added lines #L147 - L151 were not covered by tests

embed = EmbedCreator.create_embed(
bot=self.bot,
embed_type=EmbedCreator.INFO,
title="Message Bookmarked",
description=f"> {message.content}",
)
async def _get_files_from_embeds(self, message: discord.Message, files: list[discord.File]) -> None:

Check warning on line 153 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L153

Added line #L153 was not covered by tests
if len(files) >= 10:
return

Check warning on line 155 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L155

Added line #L155 was not covered by tests

embed.add_field(name="Author", value=message.author.name, inline=False)
for embed in message.embeds:
if len(files) >= 10:
break

Check warning on line 159 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L159

Added line #L159 was not covered by tests

embed.add_field(name="Jump to Message", value=f"[Click Here]({message.jump_url})", inline=False)
if embed.image and embed.image.url:
try:
async with self.session.get(embed.image.url) as resp:

Check warning on line 163 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L162-L163

Added lines #L162 - L163 were not covered by tests
if resp.status == 200:
data = await resp.read()
filename = embed.image.url.split("/")[-1].split("?")[0]
files.append(discord.File(io.BytesIO(data), filename=filename))
except aiohttp.ClientError as e:
logger.error(f"Failed to fetch embed image {embed.image.url}: {e}")

Check warning on line 169 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L165-L169

Added lines #L165 - L169 were not covered by tests

if message.attachments:
attachments_info = "\n".join([attachment.url for attachment in message.attachments])
embed.add_field(name="Attachments", value=attachments_info, inline=False)
async def _get_files_from_message(self, message: discord.Message) -> list[discord.File]:

Check warning on line 171 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L171

Added line #L171 was not covered by tests
"""
Gathers images from a message to be sent as attachments.
return embed
This function collects images from attachments, stickers, and embeds,
respecting Discord's 10-file limit.
@staticmethod
async def _send_bookmark(
user: discord.User,
message: discord.Message,
embed: discord.Embed,
emoji: discord.PartialEmoji,
) -> None:
Parameters
----------
message : discord.Message
The message to extract files from.
Returns
-------
list[discord.File]
A list of files to be attached to the bookmark message.
"""
files: list[discord.File] = []

Check warning on line 188 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L188

Added line #L188 was not covered by tests

await self._get_files_from_attachments(message, files)
await self._get_files_from_stickers(message, files)
await self._get_files_from_embeds(message, files)

Check warning on line 192 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L190-L192

Added lines #L190 - L192 were not covered by tests

return files

Check warning on line 194 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L194

Added line #L194 was not covered by tests

def _create_bookmark_embed(self, message: discord.Message) -> discord.Embed:

Check warning on line 196 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L196

Added line #L196 was not covered by tests
"""
Send a bookmarked message to the user.
Creates an embed for a bookmarked message.
This function constructs a detailed embed that includes the message content,
author, attachments, and other contextual information.
Parameters
----------
user : discord.User
The user to send the bookmarked message to.
message : discord.Message
The message that was bookmarked.
embed : discord.Embed
The embed to send to the user.
emoji : str
The emoji that was reacted to the message.
The message to create an embed from.
Returns
-------
discord.Embed
The generated bookmark embed.
"""

try:
await user.send(embed=embed)
# Get the content of the message
content = message.content or ""

Check warning on line 215 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L215

Added line #L215 was not covered by tests

# Truncate the content if it's too long
if len(content) > CONST.EMBED_MAX_DESC_LENGTH:
content = f"{content[: CONST.EMBED_MAX_DESC_LENGTH - 4]}..."

Check warning on line 219 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L219

Added line #L219 was not covered by tests

embed = EmbedCreator.create_embed(

Check warning on line 221 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L221

Added line #L221 was not covered by tests
bot=self.bot,
embed_type=EmbedCreator.INFO,
title="Message Bookmarked",
description=f"{content}" if content else "> No content available to display",
)

except (discord.Forbidden, discord.HTTPException) as dm_error:
logger.error(f"Cannot send a DM to {user.name}: {dm_error}")
# Add author to the embed
embed.set_author(

Check warning on line 229 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L229

Added line #L229 was not covered by tests
name=message.author.display_name,
icon_url=message.author.display_avatar.url,
)

# Add reference to the embed if it exists
if message.reference and message.reference.resolved:
ref_msg = message.reference.resolved

Check warning on line 236 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L236

Added line #L236 was not covered by tests
if isinstance(ref_msg, discord.Message):
embed.add_field(

Check warning on line 238 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L238

Added line #L238 was not covered by tests
name="Replying to",
value=f"[Click Here]({ref_msg.jump_url})",
)

# Add jump to message to the embed
embed.add_field(

Check warning on line 244 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L244

Added line #L244 was not covered by tests
name="Jump to Message",
value=f"[Click Here]({message.jump_url})",
)

# Add attachments to the embed
if message.attachments:
attachments = "\n".join(f"[{a.filename}]({a.url})" for a in message.attachments)
embed.add_field(name="Attachments", value=attachments, inline=False)

Check warning on line 252 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L251-L252

Added lines #L251 - L252 were not covered by tests

# Add stickers to the embed
if message.stickers:
stickers = "\n".join(f"[{s.name}]({s.url})" for s in message.stickers)
embed.add_field(name="Stickers", value=stickers, inline=False)

Check warning on line 257 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L256-L257

Added lines #L256 - L257 were not covered by tests

notify_message = await message.channel.send(
f"{user.mention}, I couldn't send you a DM. Please make sure your DMs are open for bookmarks to work.",
# Handle embeds
if message.embeds:
embed.add_field(

Check warning on line 261 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L261

Added line #L261 was not covered by tests
name="Contains Embeds",
value="Original message contains embeds which are not shown here.",
inline=False,
)

await notify_message.delete(delay=30)
# Add footer to the embed
if message.guild and isinstance(message.channel, discord.TextChannel | discord.Thread):
embed.set_footer(text=f"In #{message.channel.name} on {message.guild.name}")

Check warning on line 269 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L269

Added line #L269 was not covered by tests

# Add timestamp to the embed
embed.timestamp = message.created_at

Check warning on line 272 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L272

Added line #L272 was not covered by tests

return embed

Check warning on line 274 in tux/cogs/services/bookmarks.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/services/bookmarks.py#L274

Added line #L274 was not covered by tests


async def setup(bot: Tux) -> None:
Expand Down
18 changes: 11 additions & 7 deletions tux/cogs/utility/poll.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import cast

Check warning on line 1 in tux/cogs/utility/poll.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/utility/poll.py#L1

Added line #L1 was not covered by tests

import discord
from discord import app_commands
from discord.ext import commands
Expand Down Expand Up @@ -74,13 +76,15 @@
# get reaction from payload.message_id, payload.channel_id, payload.guild_id, payload.emoji
channel = self.bot.get_channel(payload.channel_id)
if channel is None:
logger.error(f"Channel with ID {payload.channel_id} not found.")
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Type check for channel is removed, which may allow unsupported channel types.

Without the type check, casting to TextChannel or Thread may be unsafe and could result in runtime errors if the channel is not of the expected type.

if isinstance(channel, discord.ForumChannel | discord.CategoryChannel | discord.abc.PrivateChannel):
logger.error(
f"Channel with ID {payload.channel_id} is not a compatible channel type. How the fuck did you get here?",
)
return
try:
channel = await self.bot.fetch_channel(payload.channel_id)
except discord.NotFound:
logger.error(f"Channel not found for ID: {payload.channel_id}")
return
except (discord.Forbidden, discord.HTTPException) as fetch_error:
logger.error(f"Failed to fetch channel: {fetch_error}")
return
channel = cast(discord.TextChannel | discord.Thread, channel)

Check warning on line 87 in tux/cogs/utility/poll.py

View check run for this annotation

Codecov / codecov/patch

tux/cogs/utility/poll.py#L79-L87

Added lines #L79 - L87 were not covered by tests

message = await channel.fetch_message(payload.message_id)
# Lookup the reaction object for this event
Expand Down
4 changes: 4 additions & 0 deletions tux/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,9 @@ class Constants:
EIGHT_BALL_QUESTION_LENGTH_LIMIT = 120
EIGHT_BALL_RESPONSE_WRAP_WIDTH = 30

# Bookmark constants
ADD_BOOKMARK = "🔖"
REMOVE_BOOKMARK = "🗑️"


CONST = Constants()