Birthdays
The Birthdays module tracks member birthdays and sends automated birthday wishes to a configured channel at a set daily time. Users set their own birthday once; moderators can manage birthdays for other members.
Enabling the Module
Enable the module
Dashboard → Your server → toggle Birthdays
Configure the channel
Set the Channel — the text channel where daily birthday wishes are sent
Optional: customize timing
Adjust Send Hour and Send Minute for the daily check time (default 8:00)
Save
Save changes
Channel Required
The channel_id option must be set in the dashboard. Without it, the daily birthday check runs but skips the guild — no messages are sent.
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
channel_id | string | null | Text channel ID for daily birthday wishes |
send_hour | integer | 8 | Hour of daily birthday check (24h) |
send_minute | integer | 0 | Minute of daily birthday check |
timezone_offset | integer | 2 | UTC offset (e.g., 2 for UTC+2 CEST) |
message_with_age | string | "Happy birthday {user}! 🎂 You just turned {age}!" | Message template when birth year is known |
message_without_age | string | "Happy birthday {user}! 🎂" | Message template when birth year is unknown |
ping_role | string / null | null | null (no ping), "everyone" for @everyone, or a role ID string |
color | hex string | "#FF6B2C" | Embed accent color |
Timezone
timezone_offset: 2 means UTC+2 (Central European Summer Time). Adjust for your server's timezone — e.g., 1 for CET (winter), -5 for EST.
Message Placeholders
| Placeholder | Replaced by |
|---|---|
{user} | User mention (e.g., @John) |
{age} | Age number when year is known |
{server} | Server name |
Ping Role
null— no ping, only the user mention"everyone"— prepends @everyone to the message- A role ID string (e.g.,
"123456789012345678") — pings that role
Daily Birthday Task
The bot runs a loop every minute that:
Iterates all guilds
Scans every guild where the Birthdays cog is enabled
Checks time
Compares the current time (in the guild's configured timezone) against send_hour and send_minute
Deduplication
Checks an in-memory date tracker — if wishes were already sent today, skips the guild
Queries birthdays
Fetches all users whose birthday matches today's month and day from the birthdays table
Sends embeds
For each user still in the guild, sends a styled embed with the configured message template to the configured channel
Marks sent
Records today's date to prevent duplicate sends
Send Behavior
Each birthday wish is sent as a separate message containing:
- Ping content — user mention (with optional role ping prepended)
- Embed — message text rendered in the embed description, with a footer showing the ordinal age (e.g., "🎂 25th birthday!") or "🎂 Happy Birthday!" when year is unknown
Deduplication
Deduplication is in-memory only (per-cog attribute). If the bot restarts, it may send wishes again on the same calendar day if the scheduled time has already passed.
Database
Birthdays are stored in the birthdays table:
| Column | Type | Description |
|---|---|---|
guild_id | bigint | Guild snowflake |
user_id | bigint | User snowflake |
birth_day | smallint | Day of month (1–31) |
birth_month | smallint | Month (1–12) |
birth_year | smallint | Year (optional, nullable) |
set_by | bigint | Snowflake of who set the birthday |
Unique constraint on (guild_id, user_id) — one birthday per user per guild.
Logging
Birthday actions are logged by Logs under the birthdays category:
| Event | Trigger |
|---|---|
| Birthday Set | User sets their own birthday via /birthday set |
| Birthday Set (Mod) | Moderator sets a birthday via /birthday set-user |
| Birthday Removed | Moderator removes a birthday via /birthday remove-user |
| Birthday Wish | Daily task sends a birthday wish to a channel |
Tips
Best Practices
- Set a dedicated channel like
#birthdaysfor the daily wishes - Enable the Birthdays cog for the commands to be available — users can set their birthday even if the daily channel isn't configured
- Use the
message_with_agetemplate for a personal touch when the year is known - The
{server}placeholder in templates adds a community feel to the wish
Permissions Required
The bot needs Send Messages and Embed Links permissions on the configured channel. If permissions are missing, birthday wishes fail silently (logged as a warning).