Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
4aa4acd
I'M COMMITTED!!!!
wintereye159 Aug 30, 2025
c5b3cd7
ERROR - (make_member_modal) MessageSavingSenderComponent.send() got…
wintereye159 Aug 30, 2025
d025817
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Aug 30, 2025
c6b5e7c
Formatting fixes
MattyTheHacker Aug 30, 2025
ec9e807
Merge branch 'main' into main
MattyTheHacker Aug 30, 2025
1e1c02b
Simplify
MattyTheHacker Aug 30, 2025
914bb55
Merge branch 'main' of github.com:wintereye159/VGS-Tess-TeX-Bot-Py-V2…
MattyTheHacker Aug 30, 2025
bebf4c4
AttributeError: 'Interaction' object has no attribute 'command'. Did …
wintereye159 Aug 30, 2025
ab3ee43
AttributeError: type object 'CommandChecks' has no attribute '_check_…
wintereye159 Aug 30, 2025
c1fe0e1
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Aug 30, 2025
56ec5a9
Simplify
MattyTheHacker Aug 31, 2025
cc35a2b
Refactor membership checking
MattyTheHacker Aug 31, 2025
0917ae5
Refactor and Reformat
MattyTheHacker Aug 31, 2025
2270e9c
Fix import error
MattyTheHacker Aug 31, 2025
fdda120
Bit of a mess
MattyTheHacker Aug 31, 2025
1ed9d9f
Formatting
MattyTheHacker Aug 31, 2025
797f94d
Fix
MattyTheHacker Aug 31, 2025
2ac933d
Reformat
MattyTheHacker Aug 31, 2025
74e57a6
Revert accidental change
MattyTheHacker Aug 31, 2025
fc6c1aa
Revert
MattyTheHacker Aug 31, 2025
f324842
Add logging
MattyTheHacker Aug 31, 2025
cd1899f
merge from refactor-membership-query and refactor
MattyTheHacker Aug 31, 2025
28d5036
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Aug 31, 2025
00a7121
Simplify logic
MattyTheHacker Sep 1, 2025
e548fd1
Fixes
MattyTheHacker Sep 1, 2025
93f601d
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 2, 2025
88ded71
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 2, 2025
2657358
Fixes
MattyTheHacker Sep 3, 2025
a6d1735
Docs
MattyTheHacker Sep 3, 2025
027413b
Merge branch 'main' into main
MattyTheHacker Sep 3, 2025
4835d1c
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 4, 2025
7b31100
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 4, 2025
5b4ebd6
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 5, 2025
f9209c7
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 5, 2025
6f7c436
do some stuff
MattyTheHacker Sep 7, 2025
01c9e14
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Sep 7, 2025
3777f72
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 7, 2025
3eb3e0f
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 9, 2025
6c43a5e
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 9, 2025
72c9876
Implement custom exception
MattyTheHacker Sep 11, 2025
b0f165a
Use the new exception
MattyTheHacker Sep 11, 2025
2df510a
Refactor
MattyTheHacker Sep 11, 2025
10d7f27
Merge branch 'main' into member-query-refactor
MattyTheHacker Sep 12, 2025
b5b4a39
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 12, 2025
a803f3d
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 13, 2025
8dde2bc
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 15, 2025
62f63c4
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 16, 2025
c241a2a
Merge main into member-query-refactor
automatic-pr-updater[bot] Sep 16, 2025
2308273
Fixes from review
MattyTheHacker Sep 17, 2025
07f8b8e
Fix spaces
MattyTheHacker Sep 17, 2025
0e530ba
Move logger up
MattyTheHacker Sep 17, 2025
6dffe9c
Merge branch 'member-query-refactor' into vgs-main
MattyTheHacker Sep 18, 2025
5479886
fix merge errors
MattyTheHacker Sep 18, 2025
c8a4c64
Add functionality
MattyTheHacker Sep 18, 2025
d6605cc
command_checks.py error fixed for non committee member edge-case
wintereye159 Sep 21, 2025
d9a08ee
Merge remote-tracking branch 'upstream/main'
MattyTheHacker Sep 21, 2025
2342ab5
Fixes
MattyTheHacker Sep 21, 2025
ebd7c06
ensured that guest role is added to verified member when they erify t…
wintereye159 Sep 21, 2025
e2a3237
ensured that guest role is added to verified member when they erify t…
wintereye159 Sep 26, 2025
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
122 changes: 0 additions & 122 deletions .env.example

This file was deleted.

4 changes: 3 additions & 1 deletion cogs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from .invite_link import InviteLinkCommandCog
from .kill import KillCommandCog
from .make_applicant import MakeApplicantContextCommandsCog, MakeApplicantSlashCommandCog
from .make_member import MakeMemberCommandCog, MemberCountCommandCog
from .make_member import MakeMemberCommandCog, MakeMemberModalCommandCog, MemberCountCommandCog
from .ping import PingCommandCog
from .remind_me import ClearRemindersBacklogTaskCog, RemindMeCommandCog
from .send_get_roles_reminders import SendGetRolesRemindersTaskCog
Expand Down Expand Up @@ -75,6 +75,7 @@
"MakeApplicantContextCommandsCog",
"MakeApplicantSlashCommandCog",
"MakeMemberCommandCog",
"MakeMemberModalCommandCog",
"ManualModerationCog",
"MemberCountCommandCog",
"PingCommandCog",
Expand Down Expand Up @@ -118,6 +119,7 @@ def setup(bot: "TeXBot") -> None:
MakeMemberCommandCog,
ManualModerationCog,
MemberCountCommandCog,
MakeMemberModalCommandCog,
PingCommandCog,
RemindMeCommandCog,
SendGetRolesRemindersTaskCog,
Expand Down
31 changes: 18 additions & 13 deletions cogs/induct.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,28 +93,33 @@
(
f"**Congrats on joining the {self.bot.group_short_name} Discord server "
f"as a {user_type}!** "
"You now have access to communicate in all the public channels.\n\n"
"\n\n"
)
]

if user_type == "member":
messages_to_send.append(
f"**Thank you for becomming a member of {self.bot.group_short_name}.**\n"
"you now have access to all public channels including the minecraft server and other member only channels.\n"

Check failure on line 103 in cogs/induct.py

View workflow job for this annotation

GitHub Actions / ruff-lint

Ruff (E501)

cogs/induct.py:103:96: E501 Line too long (125 > 95)
"and you now also have that shiny new Role"
)

if user_type != "member":
messages_to_send.append(
"Some things to do to get started:\n"
f"1. Check out our rules in {
await self.bot.get_mention_string(self.bot.rules_channel)
}\n"
f"2. Head to {
await self.bot.get_mention_string(self.bot.roles_channel)
} and click on the icons to get optional roles like pronouns and year groups\n"
f"2. Head to Channels & Roles in the Onboarding screen and click on the icons to get optional roles like pronouns, year groups and games\n"

Check failure on line 113 in cogs/induct.py

View workflow job for this annotation

GitHub Actions / ruff-lint

Ruff (E501)

cogs/induct.py:113:96: E501 Line too long (155 > 95)
"3. Change your nickname to whatever you wish others to refer to you as "
"(You can do this by right-clicking your name in the members-list "
'to the right & selecting "Edit Server Profile").'
)
]

if user_type != "member":
messages_to_send.append(
f"You can also get yourself an annual membership "
"You can also get yourself an annual membership "
f"to {self.bot.group_full_name} for only £5! "
f"Just head to {settings['PURCHASE_MEMBERSHIP_URL']}. "
"You'll get awesome perks like a free T-shirt:shirt:, "
"access to member only events:calendar_spiral: and a cool green name on "
f"the {self.bot.group_short_name} Discord server:green_square:! "
f"You'll get awesome perks like acess to the {self.bot.group_short_name} Minecraft server :pick:, "

Check failure on line 120 in cogs/induct.py

View workflow job for this annotation

GitHub Actions / ruff-lint

Ruff (E501)

cogs/induct.py:120:96: E501 Line too long (115 > 95)
"access to member only events :calendar_spiral: and a cool blue Role on "
f"the {self.bot.group_short_name} Discord server :blue_square:! "
f"Checkout all the perks at {settings['MEMBERSHIP_PERKS_URL']}"
)

Expand Down
152 changes: 145 additions & 7 deletions cogs/make_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@

import logging
import re
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, override

import discord
from discord.ui import Modal, View
from django.core.exceptions import ValidationError

from config import settings
from db.core.models import GroupMadeMember
from exceptions import ApplicantRoleDoesNotExistError, GuestRoleDoesNotExistError
from utils import CommandChecks, TeXBotBaseCog
from utils.msl import fetch_community_group_members_count, is_id_a_community_group_member
from utils import CommandChecks, TeXBotApplicationContext, TeXBotBaseCog
from utils.msl import (
fetch_community_group_members_count,
is_id_a_community_group_member,
)

if TYPE_CHECKING:
from collections.abc import Sequence
from logging import Logger
from typing import Final

from utils import TeXBotApplicationContext


__all__: "Sequence[str]" = ("MakeMemberCommandCog", "MemberCountCommandCog")
__all__: "Sequence[str]" = (
"MakeMemberCommandCog",
"MakeMemberModalCommandCog",
"MemberCountCommandCog",
)


logger: "Final[Logger]" = logging.getLogger("TeX-Bot")
Expand Down Expand Up @@ -225,3 +230,136 @@ async def member_count(self, ctx: "TeXBotApplicationContext") -> None: # type:
f"{await fetch_community_group_members_count()} members! :tada:"
)
)


class MakeMemberModalActual(Modal):
"""A discord.Modal containing a the input box for make member user interaction."""

@override
def __init__(self) -> None:
super().__init__(title="Make Member Modal")
self.add_item(
discord.ui.InputText(
label="Student ID",
min_length=7,
max_length=7,
required=True,
placeholder="1234567",
)
)

@override
async def callback(self, interaction: discord.Interaction) -> None:
raw_student_id: str | None = self.children[0].value
if not raw_student_id:
await interaction.response.send_message(
content="Invalid Student ID.", ephemeral=True
)
return

try:
student_id: int = int(raw_student_id)
except ValueError:
await interaction.response.send_message(
content="Student ID must be a number.", ephemeral=True
)
return

if await is_id_a_community_group_member(member_id=student_id):
await MakeMemberModalCommandCog.give_member_role(
self=MakeMemberModalCommandCog(bot=interaction.client), interaction=interaction
)
await interaction.response.send_message(content="Action complete.", ephemeral=True)
return

await interaction.response.send_message(
content="Student ID not found.", ephemeral=True
)


class OpenMemberVerifyModalView(View):
"""A discord.View containing a button to open a new member verification modal."""

def __init__(self) -> None:
super().__init__(timeout=None)

@discord.ui.button(
label="Verify", style=discord.ButtonStyle.primary, custom_id="verify_new_member"
)
async def verify_new_member_button_callback( # type: ignore[misc]
self, _: discord.Button, interaction: discord.Interaction
) -> None:
await interaction.response.send_modal(MakeMemberModalActual())


class MakeMemberModalCommandCog(TeXBotBaseCog):
"""Cog class that defines the "/make-member-modal" command and its call-back method."""

@TeXBotBaseCog.listener()
async def on_ready(self) -> None:
"""Add OpenMemberVerifyModalView to the bot's list of permanent views."""
self.bot.add_view(OpenMemberVerifyModalView())

async def give_member_role(self, interaction: discord.Interaction) -> None:
"""Give the member role to the user who interacted with the modal."""
if not isinstance(interaction.user, discord.Member):
await self.command_send_error(
ctx=TeXBotApplicationContext(bot=interaction.client, interaction=interaction),
message="User is not a member.",
)
return

await interaction.user.add_roles(
await self.bot.member_role,
reason=f'{interaction.user} used TeX Bot modal: "Make Member"',
)
try:
guest_role: discord.Role = await self.bot.guest_role
except GuestRoleDoesNotExistError:
logger.warning(
'"/make-member" command used but the "Guest" role does not exist. '
'Some user\'s may now have the "Member" role without the "Guest" role. '
'Use the "/ensure-members-inducted" command to fix this issue.'
)
else:
if guest_role not in interaction.user.roles:
await interaction.user.add_roles(
guest_role,
reason=f'{interaction.user} used TeX Bot slash-command: "/make-member"',
)

async def _open_make_new_member_modal(
self,
button_callback_channel: discord.TextChannel | discord.DMChannel,
) -> None:
await button_callback_channel.send(
content="would you like to open the make member modal",
view=OpenMemberVerifyModalView(),
)

@discord.slash_command( # type: ignore[no-untyped-call, misc]
name="make-member-modal",
description=(
"prints a message with a button that allows users to open the make member modal, "
),
)
@CommandChecks.check_interaction_user_has_committee_role
@CommandChecks.check_interaction_user_in_main_guild
async def make_member_modal( # type: ignore[misc]
self,
ctx: "TeXBotApplicationContext",
) -> None:
"""
Definition & callback response of the "make-member-modal" command.

The "make-member-modal" command prints a message with a button that allows users
to open the make member modal
"""
await self._open_make_new_member_modal(
button_callback_channel=ctx.channel,
)

await ctx.respond(
content="The make member modal has been opened in this channel.",
ephemeral=True,
)
Loading
Loading