Skip to content

Ticketing System#120

Open
a-Digi-a wants to merge 8 commits into
mainfrom
ticketing-system
Open

Ticketing System#120
a-Digi-a wants to merge 8 commits into
mainfrom
ticketing-system

Conversation

@a-Digi-a

@a-Digi-a a-Digi-a commented Jun 14, 2026

Copy link
Copy Markdown

A ticketing system where people can contact either helpdesk, admins or the entire committee privately through the Redbrick discord instead of DM's.

How it works:

  • A channel will be made for tickets (under the technical category)
  • One of the admins will need to run /create_ticket_message [new channel name]
  • A message will be sent by blockbot in the new channel, users can then click a button on this message
  • On clicking the button, users will be prompted to choose which category of committee they want to contact and fill in their reason for the ticket
  • A channel will be created with the name ticket-user-[number]
  • This channel will have a message by blockbot where users can click a button to close the ticket when solved, deleting the channel and it will ping the user/committee added

@a-Digi-a a-Digi-a self-assigned this Jun 14, 2026
@a-Digi-a a-Digi-a added the enhancement New feature or request label Jun 14, 2026
@github-project-automation github-project-automation Bot moved this to 📋 Backlog in Webgroup Jun 14, 2026
@a-Digi-a a-Digi-a linked an issue Jun 14, 2026 that may be closed by this pull request
@a-Digi-a a-Digi-a marked this pull request as draft June 14, 2026 18:51
@a-Digi-a a-Digi-a marked this pull request as ready for review June 15, 2026 15:49
Comment thread src/extensions/ticket.py
ctx: BlockbotContext,
channel_option: arc.Option[
hikari.TextableChannel,
arc.ChannelParams("A textable channel option.", name="channel"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use a better option description

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops forgot to change the boilerplate code :P

Comment thread src/extensions/ticket.py
Comment on lines +21 to +23
channel_option: arc.Option[
hikari.TextableChannel,
arc.ChannelParams("A textable channel option.", name="channel"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you call the parameter channel (instead of channel_option) you don't have to specify name="channel" ... I think...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ill check it out

Comment thread src/extensions/ticket.py
arc.ChannelParams("A textable channel option.", name="channel"),
],
) -> None:
embed = hikari.Embed(title="Tickets", description="Create a ticket here!")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could describe what you might open a ticket for

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any suggestions on what to write? I feel like I'd just make it kind of long winded explaining it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like "Need to contact admins, helpdesk, or the whole committee? Open a ticket!" maybe?

Comment thread src/extensions/ticket.py
Comment on lines +35 to +40
@plugin.listen()
async def button_click(event: hikari.InteractionCreateEvent) -> None:
if not isinstance(event.interaction, hikari.ComponentInteraction):
return
if event.interaction.custom_id != "meowmeow1":
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use a single event listener which filters events and calls functions instead

e.g.

# one listener
@plugin.listen()
async def on_interaction(event: hikari.InteractionCreateEvent) -> None:
    if isinstance(event, ComponentInteraction) and event.custom_id == "meowmeow1":
        await handle_meowmeow1(event)
    # repeat for all existing listeners

async def handle_meowmeow1(event: ComponentInteraction): # this could be ModalInteraction, etc
    ...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll refactor it

Comment thread src/extensions/ticket.py
for value in ("admins", "helpdesk", "committee"):
committee_select.add_option(value.title(), value)
committee_label = se.LabelComponentBuilder(
label="Committee", component=committee_select

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add a description here? e.g. "Who do you wish to contact"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May have forgot to do that...

Comment thread src/extensions/ticket.py
existing_names = {
channel.name
for channel in channels
if hasattr(channel, "parent_id")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you check it's an instance of a category channel (not sure what the classname is) instead of checking for an attribute

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried searching for a way to search through the channels in the category but couldn't find them

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I meant something like

isinstance(channel, hikari.GuildCategory)

instead of the hasattr check

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah i see, makes sense

Comment thread src/extensions/ticket.py
flags=hikari.MessageFlag.EPHEMERAL,
)
await event.app.rest.create_message(
created_channel.id, f"<@&{permission_role}> <@{event.interaction.user.id}>"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just pass create_channel here. Although I'd rather you include this in the original message as the content. Also, to make it actually ping the role + user, you'll have to set the user_mentions and role_mentions parameters to True

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just pass create_channel here

Idk what you mean tbh.

Although I'd rather you include this in the original message as the content.

The original message (I assume you mean the one above it) is sent in the channel for creating tickets just for that user, the new one pings the user and role for who they want to contact.

Also, to make it actually ping the role + user, you'll have to set the user_mentions and role_mentions parameters to True

Thanks I'll make sure to set those parameters.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk what you mean tbh.

create_channel instead of create_channel.id

original message

oh I meant the one with the embed send in the new channel sorry
e.g. create_message(content="<pings>", embed=embed, ...)

Comment thread src/extensions/ticket.py
hikari.ResponseType.MESSAGE_CREATE,
"Closing ticket...",
flags=hikari.MessageFlag.EPHEMERAL,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to sleep for a few seconds here (asyncio.sleep) so the user can actually see the message before the channel is deleted

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, ill make it sleep for like 3 seconds

Comment thread src/extensions/ticket.py
@github-project-automation github-project-automation Bot moved this from 📋 Backlog to 🖐 Assigned in Webgroup Jun 15, 2026
Comment thread src/config.py
Comment on lines +137 to +146
CATEGORY_IDS: dict[str, int] = {
"official": 568810044309766151,
"administration": 568810044309766151,
"technical": 1202325296133701723,
"general": 627868752310042627,
"general-bots": 1202319516407697438,
"webgroup": 1202321207811395624,
"voice-channels": 568403964098248723,
"archive": 958448000496173056,
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only category we use is technical; there is no need to include the other categories.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its mainly for future use too, there's other dictionaries for things like roles in that file I thought I might as well complete it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its mainly for future use too, there's other dictionaries for things like roles in that file I thought I might as well complete it

Okay, but make sure that the correct IDs are used instead of placeholder ones. It would also be helpful if the dictionary keys matched the category names. But it would be good to keep the config file free of unnecessary parameters.

Comment thread src/extensions/ticket.py
Comment thread src/extensions/ticket.py
async def delete_channel(event: hikari.InteractionCreateEvent) -> None:
if not isinstance(event.interaction, hikari.ComponentInteraction):
return
if event.interaction.custom_id != "moomoo1":

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite nice and funny naming, but it would be good to also have some context on the IDs used. Maybe something like moomoo-del might be better

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: 🖐 Assigned

Development

Successfully merging this pull request may close these issues.

Add ticketing system

3 participants