Skip to content
Open
Changes from all commits
Commits
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
32 changes: 21 additions & 11 deletions bot/exts/utils/reminders.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from discord.ext.commands import Cog, Context, Greedy, group
from pydis_core.site_api import ResponseCodeError
from pydis_core.utils import scheduling
from pydis_core.utils.channel import get_or_fetch_channel
from pydis_core.utils.members import get_or_fetch_member
from pydis_core.utils.scheduling import Scheduler

Expand Down Expand Up @@ -232,7 +233,7 @@ async def cog_load(self) -> None:
now = datetime.now(UTC)

for reminder in response:
is_valid, *_ = self.ensure_valid_reminder(reminder)
is_valid, *_ = await self.ensure_valid_reminder(reminder)
if not is_valid:
continue

Expand All @@ -244,19 +245,28 @@ async def cog_load(self) -> None:
else:
self.schedule_reminder(reminder)

def ensure_valid_reminder(self, reminder: dict) -> tuple[bool, discord.TextChannel]:
"""Ensure reminder channel can be fetched otherwise delete the reminder."""
channel = self.bot.get_channel(reminder["channel_id"])
is_valid = True
async def ensure_valid_reminder(self, reminder: dict) -> tuple[bool, discord.TextChannel | None]:
"""Ensure reminder channel can be fetched otherwise notify the user and delete the reminder."""
try:
channel = await get_or_fetch_channel(self.bot, reminder["channel_id"])
except discord.HTTPException:
channel = None
Comment on lines +248 to +253
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe we should be more specific about the exceptions we catch here, e.g. just notfound and forbidden, to try and avoid cancelling reminders in the case of a discord outage.


if not channel:
is_valid = False
log.info(
f"Reminder {reminder['id']} invalid: "
f"Channel {reminder['channel_id']}={channel}."
f"Channel {reminder['channel_id']} could not be fetched."
)
user = self.bot.get_user(reminder["author"])
if user:
await user.send(
f"Your reminder could not be delivered because the channel it was set in "
f"is no longer accessible.\n**Reminder content:** {reminder['content']}"
)
Comment on lines +260 to +265
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we also be attempting to DM people that were also scheduled to be mentioned in the reminder? (in reminder['mentions']`)?

scheduling.create_task(self.bot.api_client.delete(f"bot/reminders/{reminder['id']}"))
return False, None

return is_valid, channel
return True, channel

@staticmethod
async def _send_confirmation(
Expand Down Expand Up @@ -357,7 +367,7 @@ async def add_mention_opt_in(self, reminder: dict, user_id: int) -> dict:
@lock_arg(LOCK_NAMESPACE, "reminder", itemgetter("id"), raise_error=True)
async def send_reminder(self, reminder: dict, expected_time: time.Timestamp | None = None) -> None:
"""Send the reminder."""
is_valid, channel = self.ensure_valid_reminder(reminder)
is_valid, channel = await self.ensure_valid_reminder(reminder)
if not is_valid:
# No need to cancel the task too; it'll simply be done once this coroutine returns.
return
Expand Down Expand Up @@ -475,7 +485,7 @@ async def new_reminder(

# Let's limit this, so we don't get 10 000
# reminders from kip or something like that :P
if len(active_reminders) > MAXIMUM_REMINDERS:
if len(active_reminders) >= MAXIMUM_REMINDERS:
await send_denial(ctx, "You have too many active reminders!")
return

Expand Down Expand Up @@ -659,7 +669,7 @@ async def _delete_reminder(self, ctx: Context, id_: int) -> bool:
@remind_group.command("delete", aliases=("remove", "cancel"))
async def delete_reminder(self, ctx: Context, ids: Greedy[int]) -> None:
"""Delete up to (and including) 5 of your active reminders."""
if len(ids) > 5:
if len(ids) >= 5:
await send_denial(ctx, "You can only delete a maximum of 5 reminders at once.")
return
Comment on lines 671 to 674
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, surely this change is wrong...

If you can delete up to 5 reminders, you only deny if there are >5 reminders, so the original code is correct.


Expand Down