diff --git a/birthday/README.md b/birthday/README.md index 03ee037..8072132 100644 --- a/birthday/README.md +++ b/birthday/README.md @@ -1,13 +1,6 @@ # Birthday Cog for Red-DiscordBot -This cog for [Red-DiscordBot](https://github.com/Cog-Creators/Red-DiscordBot) allows server administrators to assign a special "birthday role" to users until midnight Pacific Time. - -## Features - -- Assign a birthday role to a user that automatically expires at midnight Pacific Time -- Restrict usage of the birthday command to specific roles -- Ignore role hierarchy when assigning the birthday role -- Admin commands to set up the birthday role and manage permissions +This cog allows you to assign a special role to users on their birthday and send them a celebratory message with cake (or pie) emojis! ## Installation @@ -15,58 +8,73 @@ To install this cog, follow these steps: 1. Ensure you have Red-DiscordBot V3 installed. 2. Add the repository to your bot: - ``` [p]repo add Pac-cogs https://github.com/pacnpal/Pac-cogs ``` - -3. Install the cog: - +3. Install the Birthday cog: ``` [p]cog install Pac-cogs birthday ``` +4. Load the cog: + ``` + [p]load birthday + ``` + +Replace `[p]` with your bot's prefix. + +## Setup + +Before using the cog, you need to set it up: + +1. Set the birthday role: + ``` + [p]birthdayset role @Birthday + ``` + **Note:** The bot's role must be above the birthday role in the server's role hierarchy, but users assigning the birthday role do not need to have a role above it. + +2. Add roles that can use the birthday command: + ``` + [p]birthdayset addrole @Moderator + ``` +3. (Optional) Set the timezone for role expiration: + ``` + [p]birthdayset timezone America/New_York + ``` +4. (Optional) Set a specific channel for birthday announcements: + ``` + [p]birthdayset channel #birthdays + ``` ## Usage -After installation, load the cog with: - -``` -[p]load birthday -``` - -### Admin Setup - -Before the cog can be used, an admin needs to set it up: - -1. Set the birthday role: - - ``` - [p]birthdayset role @BirthdayRole - ``` - -2. Add roles that can use the birthday command: - - ``` - [p]birthdayset addrole @AllowedRole - ``` - -### Using the Birthday Command - -Users with allowed roles can assign the birthday role to a member: - +To assign the birthday role to a user: ``` [p]birthday @User ``` -The birthday role will be automatically removed at midnight Pacific Time. +This will assign the birthday role to the user and send a celebratory message with random cake (or pie) emojis. The role will be automatically removed at midnight in the specified timezone. + +## Features + +- Assigns a special birthday role to users +- Sends a celebratory message with random cake (or pie) emojis +- Automatically removes the birthday role at midnight +- Configurable timezone for role expiration +- Option to set a specific channel for birthday announcements +- Restricts usage of the birthday command to specified roles +- Users can assign the birthday role without needing a role higher than it in the hierarchy ## Commands -- `[p]birthdayset role @Role`: Set the birthday role -- `[p]birthdayset addrole @Role`: Add a role that can use the birthday command -- `[p]birthdayset removerole @Role`: Remove a role from using the birthday command -- `[p]birthday @User`: Assign the birthday role to a user +- `[p]birthdayset role`: Set the birthday role +- `[p]birthdayset addrole`: Add a role that can use the birthday command +- `[p]birthdayset removerole`: Remove a role from using the birthday command +- `[p]birthdayset timezone`: Set the timezone for the birthday role expiration +- `[p]birthdayset channel`: Set the channel for birthday announcements +- `[p]birthday`: Assign the birthday role to a user -## License +## Support -This project is licensed under the Creative Commons Attribution 4.0 International License - see the [LICENSE](LICENSE) file for details. +If you encounter any issues or have questions, please open an issue on the [GitHub repository](https://github.com/pacnpal/Pac-cogs). + +Enjoy celebrating birthdays with your Discord community! \ No newline at end of file diff --git a/birthday/birthday.py b/birthday/birthday.py index bb1706b..b14a273 100644 --- a/birthday/birthday.py +++ b/birthday/birthday.py @@ -3,16 +3,20 @@ from redbot.core import commands, checks from redbot.core.bot import Red from redbot.core.config import Config from datetime import datetime, time, timedelta +from zoneinfo import ZoneInfo, ZoneInfoNotFoundError +import random class Birthday(commands.Cog): - """A cog to assign a birthday role until midnight Pacific Time.""" + """A cog to assign a birthday role until midnight in a specified timezone.""" def __init__(self, bot: Red): self.bot = bot self.config = Config.get_conf(self, identifier=1234567890) default_guild = { "birthday_role": None, - "allowed_roles": [] + "allowed_roles": [], + "timezone": "UTC", + "birthday_channel": None } self.config.register_guild(**default_guild) self.birthday_tasks = {} @@ -45,9 +49,27 @@ class Birthday(commands.Cog): allowed_roles.remove(role.id) await ctx.send(f"Removed {role.name} from the list of roles that can use the birthday command.") + @birthdayset.command() + @checks.is_owner() + async def timezone(self, ctx, tz: str): + """Set the timezone for the birthday role expiration.""" + try: + ZoneInfo(tz) + await self.config.guild(ctx.guild).timezone.set(tz) + await ctx.send(f"Timezone set to {tz}") + except ZoneInfoNotFoundError: + await ctx.send(f"Invalid timezone: {tz}. Please use a valid IANA time zone identifier.") + + @birthdayset.command() + @checks.is_owner() + async def channel(self, ctx, channel: discord.TextChannel): + """Set the channel for birthday announcements.""" + await self.config.guild(ctx.guild).birthday_channel.set(channel.id) + await ctx.send(f"Birthday announcement channel set to {channel.mention}") + @commands.command() async def birthday(self, ctx, member: discord.Member): - """Assign the birthday role to a user until midnight Pacific Time.""" + """Assign the birthday role to a user until midnight in the set timezone.""" # Check if the user has permission to use this command allowed_roles = await self.config.guild(ctx.guild).allowed_roles() if not any(role.id in allowed_roles for role in ctx.author.roles): @@ -67,19 +89,38 @@ class Birthday(commands.Cog): except discord.Forbidden: return await ctx.send("I don't have permission to assign that role.") - await ctx.send(f"🎉 Happy Birthday, {member.mention}! You've been given the {birthday_role.name} role until midnight Pacific Time.") + timezone = await self.config.guild(ctx.guild).timezone() + + # Get the birthday announcement channel + birthday_channel_id = await self.config.guild(ctx.guild).birthday_channel() + if birthday_channel_id: + channel = self.bot.get_channel(birthday_channel_id) + else: + channel = ctx.channel + + # Generate birthday message with random cakes (or pie) + cakes = random.randint(0, 5) + if cakes == 0: + message = f"🎉 Happy Birthday, {member.mention}! Sorry, out of cake today! Here's pie instead: 🥧" + else: + message = f"🎉 Happy Birthday, {member.mention}! Here's your cake{'s' if cakes > 1 else ''}: " + "🎂" * cakes + + await channel.send(message) # Schedule role removal - utc_now = datetime.utcnow() - pacific_offset = timedelta(hours=-8) # Pacific Standard Time offset - pacific_now = utc_now + pacific_offset - pacific_midnight = datetime.combine(pacific_now.date() + timedelta(days=1), time.min) - utc_midnight = pacific_midnight - pacific_offset + try: + tz = ZoneInfo(timezone) + except ZoneInfoNotFoundError: + await ctx.send(f"Warning: Invalid timezone set. Defaulting to UTC.") + tz = ZoneInfo("UTC") + + now = datetime.now(tz) + midnight = datetime.combine(now.date() + timedelta(days=1), time.min).replace(tzinfo=tz) if ctx.guild.id in self.birthday_tasks: self.birthday_tasks[ctx.guild.id].cancel() - self.birthday_tasks[ctx.guild.id] = self.bot.loop.create_task(self.remove_birthday_role(ctx.guild, member, birthday_role, utc_midnight)) + self.birthday_tasks[ctx.guild.id] = self.bot.loop.create_task(self.remove_birthday_role(ctx.guild, member, birthday_role, midnight)) async def remove_birthday_role(self, guild, member, role, when): """Remove the birthday role at the specified time."""