diff --git a/.env.example b/.env.example index c1149c346..513acfcdd 100644 --- a/.env.example +++ b/.env.example @@ -26,6 +26,10 @@ GROUP_SHORT_NAME=[Replace with the short colloquial name of your community group # Must be a valid URL PURCHASE_MEMBERSHIP_URL=[Replace with your group\'s purchase=membership URL] +# The invite link URL to allow users to join your community group's Discord server +# Must be a valid URL +DISCORD_INVITE_URL=[Replace with your group\'s Discord server invite link] + # The minimum level that logs must meet in order to be logged to the console output stream # One of: DEBUG, INFO, WARNING, ERROR, CRITICAL diff --git a/cogs/__init__.py b/cogs/__init__.py index 068641872..e97071fa9 100644 --- a/cogs/__init__.py +++ b/cogs/__init__.py @@ -28,6 +28,7 @@ InductSendMessageCog, InductSlashCommandCog, ) +from .invite_link import InviteLinkCommandCog from .kill import KillCommandCog from .make_applicant import MakeApplicantContextCommandsCog, MakeApplicantSlashCommandCog from .make_member import MakeMemberCommandCog, MemberCountCommandCog @@ -63,6 +64,7 @@ "InductContextCommandsCog", "InductSendMessageCog", "InductSlashCommandCog", + "InviteLinkCommandCog", "KillCommandCog", "MakeApplicantContextCommandsCog", "MakeApplicantSlashCommandCog", @@ -103,6 +105,7 @@ def setup(bot: "TeXBot") -> None: InductSendMessageCog, InductSlashCommandCog, KillCommandCog, + InviteLinkCommandCog, MakeApplicantContextCommandsCog, MakeApplicantSlashCommandCog, MakeMemberCommandCog, diff --git a/cogs/invite_link.py b/cogs/invite_link.py new file mode 100644 index 000000000..d36f27ccc --- /dev/null +++ b/cogs/invite_link.py @@ -0,0 +1,32 @@ +"""Contains cog classes for any invite link display interactions.""" + +from typing import TYPE_CHECKING + +import discord + +from config import settings +from utils import TeXBotBaseCog + +if TYPE_CHECKING: + from collections.abc import Sequence + + from utils import TeXBotApplicationContext + +__all__: "Sequence[str]" = ("InviteLinkCommandCog",) + + +class InviteLinkCommandCog(TeXBotBaseCog): + """Cog class that defines the "/invite-link" command and its call-back method.""" + + @discord.slash_command( # type: ignore[no-untyped-call, misc] + name="invite-link", description="Display the invite link to this server." + ) + async def invite_link(self, ctx: "TeXBotApplicationContext") -> None: # type: ignore[misc] + """Definition & callback response of the "invite-link" command.""" + await ctx.respond( + ( + f"Invite your friends to the {self.bot.group_short_name} Discord server: " + f"{settings['DISCORD_INVITE_URL']}" + ), + ephemeral=False, + ) diff --git a/config.py b/config.py index a401be2e6..985063cff 100644 --- a/config.py +++ b/config.py @@ -291,6 +291,21 @@ def _setup_membership_perks_url(cls) -> None: cls._settings["MEMBERSHIP_PERKS_URL"] = raw_membership_perks_url + @classmethod + def _setup_discord_invite_url(cls) -> None: + raw_discord_invite_url: str | None = os.getenv("DISCORD_INVITE_URL") + + DISCORD_INVITE_URL_IS_VALID: Final[bool] = bool( + not raw_discord_invite_url or validators.url(raw_discord_invite_url), + ) + if not DISCORD_INVITE_URL_IS_VALID: + INVALID_DISCORD_INVITE_URL_MESSAGE: Final[str] = ( + "DISCORD_INVITE_URL must be a valid URL." + ) + raise ImproperlyConfiguredError(INVALID_DISCORD_INVITE_URL_MESSAGE) + + cls._settings["DISCORD_INVITE_URL"] = raw_discord_invite_url + @classmethod def _setup_ping_command_easter_egg_probability(cls) -> None: INVALID_PING_COMMAND_EASTER_EGG_PROBABILITY_MESSAGE: Final[str] = ( @@ -738,6 +753,7 @@ def _setup_env_variables(cls) -> None: cls._setup_members_list_auth_session_cookie() cls._setup_membership_perks_url() cls._setup_purchase_membership_url() + cls._setup_discord_invite_url() cls._setup_send_introduction_reminders() cls._setup_send_introduction_reminders_delay() cls._setup_send_introduction_reminders_interval()