Add /remind interval
This commit is contained in:
@ -91,6 +91,10 @@ class RemindGroup(discord.app_commands.Group):
|
||||
user (discord.User, optional): Send reminder as a DM to this user. Defaults to None.
|
||||
dm_and_current_channel (bool, optional): Send reminder as a DM to the user and in this channel. Defaults to False.
|
||||
""" # noqa: E501
|
||||
# TODO(TheLovinator): Add try/except for all of these await calls # noqa: TD003
|
||||
# TODO(TheLovinator): Add a warning if the interval is too short # noqa: TD003
|
||||
# TODO(TheLovinator): Check if we have access to the channel and user# noqa: TD003
|
||||
|
||||
should_send_channel_reminder = True
|
||||
|
||||
await interaction.response.defer()
|
||||
@ -210,6 +214,10 @@ class RemindGroup(discord.app_commands.Group):
|
||||
user (discord.User, optional): Send reminder as a DM to this user. Defaults to None.
|
||||
dm_and_current_channel (bool, optional): If user is provided, send reminder as a DM to the user and in this channel. Defaults to only the user.
|
||||
""" # noqa: E501
|
||||
# TODO(TheLovinator): Add try/except for all of these await calls # noqa: TD003
|
||||
# TODO(TheLovinator): Add a warning if the interval is too short # noqa: TD003
|
||||
# TODO(TheLovinator): Check if we have access to the channel and user# noqa: TD003
|
||||
|
||||
# Log kwargs
|
||||
logger.info("New cron job from %s (%s) in %s", interaction.user, interaction.user.id, interaction.channel)
|
||||
logger.info("Cron job arguments: %s", {k: v for k, v in locals().items() if k != "self" and v is not None})
|
||||
@ -283,6 +291,119 @@ class RemindGroup(discord.app_commands.Group):
|
||||
f"First run in {calculate(channel_job)} with the message:\n**{message}**.",
|
||||
)
|
||||
|
||||
# /remind interval
|
||||
@discord.app_commands.command(
|
||||
name="interval",
|
||||
description="Create a new reminder that triggers based on an interval.",
|
||||
)
|
||||
async def interval( # noqa: PLR0913, PLR0917
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
message: str,
|
||||
weeks: int = 0,
|
||||
days: int = 0,
|
||||
hours: int = 0,
|
||||
minutes: int = 0,
|
||||
seconds: int = 0,
|
||||
start_date: str | None = None,
|
||||
end_date: str | None = None,
|
||||
timezone: str | None = None,
|
||||
jitter: int | None = None,
|
||||
channel: discord.TextChannel | None = None,
|
||||
user: discord.User | None = None,
|
||||
dm_and_current_channel: bool | None = None, # noqa: FBT001
|
||||
) -> None:
|
||||
"""Create a new reminder that triggers based on an interval.
|
||||
|
||||
Args:
|
||||
interaction (discord.Interaction): The interaction object for the command.
|
||||
message (str): The content of the reminder.
|
||||
weeks (int, optional): Number of weeks between each run. Defaults to 0.
|
||||
days (int, optional): Number of days between each run. Defaults to 0.
|
||||
hours (int, optional): Number of hours between each run. Defaults to 0.
|
||||
minutes (int, optional): Number of minutes between each run. Defaults to 0.
|
||||
seconds (int, optional): Number of seconds between each run. Defaults to 0.
|
||||
start_date (str, optional): Earliest possible date/time to trigger on (inclusive). Will get parsed.
|
||||
end_date (str, optional): Latest possible date/time to trigger on (inclusive). Will get parsed.
|
||||
timezone (str, optional): Time zone to use for the date/time calculations Defaults to scheduler timezone.
|
||||
jitter (int, optional): Delay the job execution by jitter seconds at most.
|
||||
channel (discord.TextChannel, optional): The channel to send the reminder to. Defaults to current channel.
|
||||
user (discord.User, optional): Send reminder as a DM to this user. Defaults to None.
|
||||
dm_and_current_channel (bool, optional): If user is provided, send reminder as a DM to the user and in this channel. Defaults to only the user.
|
||||
""" # noqa: E501
|
||||
# TODO(TheLovinator): Add try/except for all of these await calls # noqa: TD003
|
||||
# TODO(TheLovinator): Add a warning if the interval is too short # noqa: TD003
|
||||
# TODO(TheLovinator): Check if we have access to the channel and user# noqa: TD003
|
||||
|
||||
logger.info("New interval job from %s (%s) in %s", interaction.user, interaction.user.id, interaction.channel)
|
||||
logger.info("Interval job arguments: %s", {k: v for k, v in locals().items() if k != "self" and v is not None})
|
||||
|
||||
# Get the channel ID
|
||||
channel_id: int | None = self.get_channel_id(interaction=interaction, channel=channel)
|
||||
if not channel_id:
|
||||
await interaction.followup.send(content="Failed to get channel.")
|
||||
return
|
||||
|
||||
# Ensure the guild is valid
|
||||
guild: discord.Guild | None = interaction.guild or None
|
||||
if not guild:
|
||||
await interaction.followup.send(content="Failed to get guild.")
|
||||
return
|
||||
|
||||
# Helper to add a job
|
||||
def add_job(func: Callable, job_kwargs: dict[str, int | str]) -> Job:
|
||||
return settings.scheduler.add_job(
|
||||
func=func,
|
||||
trigger="interval",
|
||||
weeks=weeks,
|
||||
days=days,
|
||||
hours=hours,
|
||||
minutes=minutes,
|
||||
seconds=seconds,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
timezone=timezone,
|
||||
jitter=jitter,
|
||||
kwargs=job_kwargs,
|
||||
)
|
||||
|
||||
# Create user DM reminder job if user is specified
|
||||
dm_message: str = ""
|
||||
if user:
|
||||
dm_job: Job = add_job(
|
||||
func=send_to_user,
|
||||
job_kwargs={
|
||||
"user_id": user.id,
|
||||
"guild_id": guild.id,
|
||||
"message": message,
|
||||
},
|
||||
)
|
||||
dm_message = f" and a DM to {user.display_name} "
|
||||
if not dm_and_current_channel:
|
||||
# If only DM is required, notify about the DM job and exit
|
||||
await interaction.followup.send(
|
||||
content=f"Hello {interaction.user.display_name},\n"
|
||||
f"I will send a DM to {user.display_name} at:\n"
|
||||
f"First run in {calculate(dm_job)} with the message:\n**{message}**.",
|
||||
)
|
||||
|
||||
# Create channel reminder job
|
||||
channel_job: Job = add_job(
|
||||
func=send_to_discord,
|
||||
job_kwargs={
|
||||
"channel_id": channel_id,
|
||||
"message": message,
|
||||
"author_id": interaction.user.id,
|
||||
},
|
||||
)
|
||||
|
||||
# Compose the final message
|
||||
await interaction.followup.send(
|
||||
content=f"Hello {interaction.user.display_name},\n"
|
||||
f"I will notify you in <#{channel_id}>{dm_message}.\n"
|
||||
f"First run in {calculate(channel_job)} with the message:\n**{message}**.",
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_channel_id(interaction: discord.Interaction, channel: discord.TextChannel | None) -> int | None:
|
||||
"""Get the channel ID to send the reminder to.
|
||||
|
@ -294,7 +294,7 @@ class JobManagementView(discord.ui.View):
|
||||
|
||||
logger.info("Deleting job: %s", self.job.id)
|
||||
if hasattr(self.job, "__getstate__"):
|
||||
logger.error("State: %s", self.job.__getstate__() if hasattr(self.job, "__getstate__") else "No state")
|
||||
logger.debug("State: %s", self.job.__getstate__() if hasattr(self.job, "__getstate__") else "No state")
|
||||
|
||||
# Log extra kwargs
|
||||
for key, value in job_kwargs.items():
|
||||
@ -316,7 +316,8 @@ class JobManagementView(discord.ui.View):
|
||||
Returns:
|
||||
str: The deletion message.
|
||||
"""
|
||||
msg: str = f"# Job *{job_kwargs.get('message'), 'No message'}* has been deleted.\n"
|
||||
job_msg: str | int = job_kwargs.get("message", "No message found")
|
||||
msg: str = f"# Job *{job_msg}* has been deleted.\n"
|
||||
msg += f"**Job ID**: {self.job.id}\n"
|
||||
|
||||
# The time the job was supposed to run
|
||||
@ -390,7 +391,7 @@ class JobManagementView(discord.ui.View):
|
||||
"""
|
||||
logger.info("Modifying job: %s", self.job.id)
|
||||
if hasattr(self.job, "__getstate__"):
|
||||
logger.error("State: %s", self.job.__getstate__() if hasattr(self.job, "__getstate__") else "No state")
|
||||
logger.debug("State: %s", self.job.__getstate__() if hasattr(self.job, "__getstate__") else "No state")
|
||||
|
||||
modal = ModifyJobModal(self.job, self.scheduler)
|
||||
await interaction.response.send_modal(modal)
|
||||
|
Reference in New Issue
Block a user