tickets_plus.cogs.staff
Staff-only commands cog for Tickets+.
Seperated from the main cog to keep things clean. Keeps the staff-only commands in clear view.
Typical usage example:
from tickets_plus import bot bot_instance = bot.TicketsPlusBot(...) await bot_instance.load_extension("tickets_plus.cogs.staff")
1"""Staff-only commands cog for Tickets+. 2 3Seperated from the main cog to keep things clean. 4Keeps the staff-only commands in clear view. 5 6Typical usage example: 7 ```py 8 from tickets_plus import bot 9 bot_instance = bot.TicketsPlusBot(...) 10 await bot_instance.load_extension("tickets_plus.cogs.staff") 11 ``` 12""" 13# License: EPL-2.0 14# SPDX-License-Identifier: EPL-2.0 15# Copyright (c) 2021-present The Tickets+ Contributors 16# This Source Code may also be made available under the following 17# Secondary Licenses when the conditions for such availability set forth 18# in the Eclipse Public License, v. 2.0 are satisfied: GPL-3.0-only OR 19# If later approved by the Initial Contributor, GPL-3.0-or-later. 20 21import datetime 22import logging 23import string 24 25import discord 26from discord import app_commands, utils 27from discord.ext import commands 28 29from tickets_plus import bot 30from tickets_plus.ext import checks, exceptions 31 32 33class StaffCmmd(commands.Cog, name="StaffCommands"): 34 """Staff-only commands for Tickets+. 35 36 This cog contains all staff-only commands. These commands are 37 only available to users with the staff role, and are used to 38 manage the bot and the tickets. 39 """ 40 41 def __init__(self, bot_instance: bot.TicketsPlusBot) -> None: 42 """Initialises the cog instance. 43 44 We store some attributes here for later use. 45 46 Args: 47 bot_instance: The bot instance. 48 """ 49 self._bt = bot_instance 50 logging.info("Loaded %s", self.__class__.__name__) 51 52 @app_commands.command(name="respond", description="Respond to a ticket as the bot.") 53 @app_commands.guild_only() 54 @checks.is_staff_check() 55 @app_commands.describe(message="The message to send to the ticket.") 56 async def respond(self, ctx: discord.Interaction, message: str) -> None: 57 """Respond to a ticket as the bot. 58 59 This command is used to respond to a ticket as the bot. 60 It can be used in a ticket channel or a staff notes thread. 61 It then sends the message to the ticket as the bot. 62 63 Args: 64 ctx: The interaction context. 65 message: The message to send to the ticket. 66 67 Raises: 68 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 69 Raised if the command is used in a channel that is not a ticket 70 or a staff notes thread. 71 """ 72 await ctx.response.defer(ephemeral=True) 73 async with self._bt.get_connection() as confg: 74 guild = await confg.get_guild(ctx.guild_id) # type: ignore # checked in decorator 75 if not ctx.user.resolved_permissions.mention_everyone: 76 message = utils.escape_mentions(message) 77 if isinstance(ctx.channel, discord.Thread): 78 ticket = await confg.fetch_ticket(ctx.channel.parent.id) 79 if ticket is None: 80 raise exceptions.InvalidLocation("The parent channel is not a ticket.") 81 if ticket.staff_note_thread != ctx.channel.id: 82 raise exceptions.InvalidLocation("This channel is not the designated staff" 83 " notes thread.") 84 await ctx.followup.send(f"Responding to ticket with message:\n{message}") 85 await ctx.channel.parent.send( # type: ignore 86 f"**{guild.staff_team_name}:** {message}") 87 88 elif isinstance(ctx.channel, discord.TextChannel): 89 ticket = await confg.fetch_ticket(ctx.channel.id) 90 if ticket is None: 91 raise exceptions.InvalidLocation("This channel is not a ticket." 92 " If it is, use /register.") 93 await ctx.followup.send( 94 f"Responding to ticket with message:\n{message}", 95 ephemeral=True, 96 ) 97 await ctx.channel.send(f"**{guild.staff_team_name}:** {message}") 98 99 await confg.close() 100 101 @app_commands.command(name="join", description="Join a ticket's staff notes.") 102 @app_commands.guild_only() 103 @checks.is_staff_check() 104 async def join(self, ctx: discord.Interaction) -> None: 105 """Adds the user to the ticket's staff note thread. 106 107 This command is used to add the user to the ticket's staff notes thread. 108 It's used to allow staff to join notes without the need for the 109 user to have the Manage Threads permission. 110 111 Args: 112 ctx: The interaction context. 113 114 Raises: 115 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 116 Raised if the command is used in a channel that is not a ticket 117 or there is no staff notes thread. 118 `tickets_plus.ext.exceptions.ReferenceNotFound`: Thread missing. 119 Raised if the staff notes thread is missing. 120 """ 121 await ctx.response.defer(ephemeral=True) 122 async with self._bt.get_connection() as confg: 123 # We don't need an account for DMs here, due to the guild_only. 124 ticket = await confg.fetch_ticket(ctx.channel.id) # type: ignore 125 if ticket is None: 126 raise exceptions.InvalidLocation("This channel is not a ticket." 127 " If it is, use /register.") 128 if ticket.staff_note_thread is None: 129 raise exceptions.InvalidLocation("This ticket has no staff notes.") 130 thred = ctx.guild.get_thread( # type: ignore 131 ticket.staff_note_thread) 132 if thred is None: 133 raise exceptions.ReferenceNotFound("This ticket's staff notes thread is missing." 134 " Was it deleted?") 135 emd = discord.Embed(title="Success!", 136 description="You have joined the staff notes thread.", 137 color=discord.Color.green()) 138 await thred.add_user(ctx.user) 139 await ctx.followup.send(embed=emd, ephemeral=True) 140 141 @app_commands.command(name="anonymize", description="Toggle anonymous staff responses.") 142 @app_commands.guild_only() 143 @checks.is_staff_check() 144 async def anonymize(self, ctx: discord.Interaction) -> None: 145 """Toggle anonymous staff responses. 146 147 This command is used to toggle anonymous staff responses. 148 The implementation itself is in events.py. 149 150 Args: 151 ctx: The interaction context. 152 153 Raises: 154 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 155 Raised if the command is used in a channel that is not a ticket. 156 """ 157 await ctx.response.defer(ephemeral=True) 158 async with self._bt.get_connection() as confg: 159 # Checked by discord in decorator 160 ticket = await confg.fetch_ticket(ctx.channel.id) # type: ignore 161 if ticket is None: 162 raise exceptions.InvalidLocation("This channel is not a ticket.") 163 ticket.anonymous = not ticket.anonymous 164 status = ticket.anonymous 165 await confg.commit() 166 emd = discord.Embed(title="Success!", 167 description=f"Anonymous staff responses are now {status}.", 168 color=discord.Color.green() if status else discord.Color.red()) 169 await ctx.followup.send(embed=emd, ephemeral=True) 170 171 @app_commands.command(name="register", description="Register an existing channel as a ticket.") 172 @app_commands.describe(thread="The staff notes thread for the ticket.") 173 @app_commands.guild_only() 174 @checks.is_staff_check() 175 async def register(self, ctx: discord.Interaction, thread: discord.Thread | None = None) -> None: 176 """A migration command to register an existing channel as a ticket. 177 178 We have this command to allow users to migrate from the old version, 179 or add channels that the bot has missed while it was offline. 180 It basically just tells the bot to start tracking the channel. 181 182 Args: 183 ctx: The interaction context. 184 thread: The staff notes thread for the ticket. 185 186 Raises: 187 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 188 If the channel is already a ticket. 189 Or the execution space is not a text channel. 190 """ 191 await ctx.response.defer(ephemeral=True) 192 if isinstance(ctx.channel, discord.TextChannel): 193 channel = ctx.channel 194 async with self._bt.get_connection() as confg: 195 guild = await confg.get_guild(ctx.guild_id) # type: ignore # checked in decorator 196 if thread is None and guild.legacy_threads: 197 thread = await channel.create_thread( 198 name="Staff Notes", 199 reason=f"Staff notes for Ticket {channel.name}", 200 auto_archive_duration=10080, 201 ) 202 await thread.send(string.Template(guild.open_message).safe_substitute(channel=channel.mention)) 203 new, ticket = await confg.get_ticket( 204 ctx.channel.id, 205 ctx.guild_id, # type: ignore 206 thread.id) 207 # Unused, we just want to check if it's new and commit it. 208 del ticket 209 if not new: 210 raise exceptions.InvalidLocation("This channel is already a ticket.") 211 await confg.commit() 212 emd = discord.Embed(title="Success!", 213 description="Registered channel as a ticket.", 214 color=discord.Color.green()) 215 await ctx.followup.send(embed=emd, ephemeral=True) 216 return 217 raise exceptions.InvalidLocation("Invalid command execution space.") 218 219 @app_commands.command(name="usrstatus", description="Set a new user status.") 220 @app_commands.guild_only() 221 @checks.is_staff_check() 222 @app_commands.describe( 223 target="The user to set the status for.", 224 status="The new status.", 225 days="The new status time days.", 226 hours="The new status time hours.", 227 minutes="The new status time minutes.", 228 ) 229 @app_commands.choices(status=[ 230 app_commands.Choice(name="None", value=0), 231 app_commands.Choice(name="Support Blocked", value=1), 232 app_commands.Choice(name="Community Support Blocked", value=2), 233 ]) 234 async def usrstatus(self, 235 interaction: discord.Interaction, 236 target: discord.Member, 237 status: app_commands.Choice[int], 238 days: int = 0, 239 hours: int = 0, 240 minutes: int = 0) -> None: 241 """Set a new user status. 242 243 This command is used to set a new user status. 244 It's used to block users from opening tickets or from getting support. 245 246 Args: 247 interaction: Discord interaction. 248 target: The user to set the status for. 249 status: The new status. 250 days: The new status time days. 251 hours: The new status time hours. 252 minutes: The new status time minutes. 253 """ 254 await interaction.response.defer(ephemeral=True) 255 async with self._bt.get_connection() as confg: 256 member = await confg.get_member( 257 target.id, 258 interaction.guild_id # type: ignore 259 ) 260 member.status = status.value 261 if status.value == 0: 262 member.status_till = None 263 await confg.commit() 264 emd = discord.Embed(title="Success!", 265 description=f"Removed status from {target.mention}.", 266 color=discord.Color.green()) 267 emd2 = discord.Embed(title="Status Removed", 268 description=(f"Your status in {target.guild.name} has been removed" 269 f" by {interaction.user.display_name}."), 270 color=discord.Color.green()) 271 else: 272 if days + hours + minutes == 0: 273 penalty_time = "Indefinitely" 274 member.status_till = None 275 else: 276 penalty_time = datetime.timedelta(days=days, hours=hours, minutes=minutes) 277 member.status_till = utils.utcnow() + penalty_time 278 if status.value == 1: 279 if member.guild.support_block is None: 280 raise exceptions.InvalidParameters("The support block role has not been set.\n" 281 "This may be intentional.\n" 282 "If not please set it up using the /settings.") 283 await target.add_roles(discord.Object(member.guild.support_block)) 284 emd = discord.Embed(title="Success!", 285 description=(f"Blocked {target.mention} from opening tickets" 286 f" for {str(penalty_time)}."), 287 color=discord.Color.red()) 288 emd2 = discord.Embed(title="Support Blocked", 289 description=("You have been blocked from opening tickets from" 290 f" {target.guild.name} for {str(penalty_time)}."), 291 color=discord.Color.red()) 292 else: 293 if member.guild.helping_block is None: 294 raise exceptions.InvalidParameters("The helping block role has not been set.\n" 295 "This may be intentional.\n" 296 "If not please set it up using the /settings.") 297 await target.add_roles(discord.Object(member.guild.helping_block)) 298 emd = discord.Embed(title="Success!", 299 description=(f"Blocked {target.mention} " 300 f"from providing support for {str(penalty_time)}."), 301 color=discord.Color.red()) 302 emd2 = discord.Embed(title="Community Support Blocked", 303 description=("You have been blocked from providing " 304 f"support from {target.guild.name}" 305 f" for {str(penalty_time)}."), 306 color=discord.Color.red()) 307 if member.guild.strip_roles: 308 roles = await confg.get_all_community_roles(interaction.guild_id) # type: ignore 309 unpck = [discord.Object(rle.role_id) for rle in roles] 310 await target.remove_roles(*unpck, reason="Community Support Blocked") 311 await confg.commit() 312 await interaction.followup.send(embed=emd, ephemeral=True) 313 try: 314 await target.send(embed=emd2) 315 except discord.Forbidden: 316 logging.debug("Failed to send status message to user.") 317 318 319async def setup(bot_instance: bot.TicketsPlusBot) -> None: 320 """Setup function for the StaffCmmd cog. 321 322 Adds the StaffCmmd cog to the bot. 323 Automatically called by the bot. 324 325 Args: 326 bot_instance: The bot instance. 327 """ 328 await bot_instance.add_cog(StaffCmmd(bot_instance))
class
StaffCmmd(discord.ext.commands.cog.Cog):
34class StaffCmmd(commands.Cog, name="StaffCommands"): 35 """Staff-only commands for Tickets+. 36 37 This cog contains all staff-only commands. These commands are 38 only available to users with the staff role, and are used to 39 manage the bot and the tickets. 40 """ 41 42 def __init__(self, bot_instance: bot.TicketsPlusBot) -> None: 43 """Initialises the cog instance. 44 45 We store some attributes here for later use. 46 47 Args: 48 bot_instance: The bot instance. 49 """ 50 self._bt = bot_instance 51 logging.info("Loaded %s", self.__class__.__name__) 52 53 @app_commands.command(name="respond", description="Respond to a ticket as the bot.") 54 @app_commands.guild_only() 55 @checks.is_staff_check() 56 @app_commands.describe(message="The message to send to the ticket.") 57 async def respond(self, ctx: discord.Interaction, message: str) -> None: 58 """Respond to a ticket as the bot. 59 60 This command is used to respond to a ticket as the bot. 61 It can be used in a ticket channel or a staff notes thread. 62 It then sends the message to the ticket as the bot. 63 64 Args: 65 ctx: The interaction context. 66 message: The message to send to the ticket. 67 68 Raises: 69 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 70 Raised if the command is used in a channel that is not a ticket 71 or a staff notes thread. 72 """ 73 await ctx.response.defer(ephemeral=True) 74 async with self._bt.get_connection() as confg: 75 guild = await confg.get_guild(ctx.guild_id) # type: ignore # checked in decorator 76 if not ctx.user.resolved_permissions.mention_everyone: 77 message = utils.escape_mentions(message) 78 if isinstance(ctx.channel, discord.Thread): 79 ticket = await confg.fetch_ticket(ctx.channel.parent.id) 80 if ticket is None: 81 raise exceptions.InvalidLocation("The parent channel is not a ticket.") 82 if ticket.staff_note_thread != ctx.channel.id: 83 raise exceptions.InvalidLocation("This channel is not the designated staff" 84 " notes thread.") 85 await ctx.followup.send(f"Responding to ticket with message:\n{message}") 86 await ctx.channel.parent.send( # type: ignore 87 f"**{guild.staff_team_name}:** {message}") 88 89 elif isinstance(ctx.channel, discord.TextChannel): 90 ticket = await confg.fetch_ticket(ctx.channel.id) 91 if ticket is None: 92 raise exceptions.InvalidLocation("This channel is not a ticket." 93 " If it is, use /register.") 94 await ctx.followup.send( 95 f"Responding to ticket with message:\n{message}", 96 ephemeral=True, 97 ) 98 await ctx.channel.send(f"**{guild.staff_team_name}:** {message}") 99 100 await confg.close() 101 102 @app_commands.command(name="join", description="Join a ticket's staff notes.") 103 @app_commands.guild_only() 104 @checks.is_staff_check() 105 async def join(self, ctx: discord.Interaction) -> None: 106 """Adds the user to the ticket's staff note thread. 107 108 This command is used to add the user to the ticket's staff notes thread. 109 It's used to allow staff to join notes without the need for the 110 user to have the Manage Threads permission. 111 112 Args: 113 ctx: The interaction context. 114 115 Raises: 116 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 117 Raised if the command is used in a channel that is not a ticket 118 or there is no staff notes thread. 119 `tickets_plus.ext.exceptions.ReferenceNotFound`: Thread missing. 120 Raised if the staff notes thread is missing. 121 """ 122 await ctx.response.defer(ephemeral=True) 123 async with self._bt.get_connection() as confg: 124 # We don't need an account for DMs here, due to the guild_only. 125 ticket = await confg.fetch_ticket(ctx.channel.id) # type: ignore 126 if ticket is None: 127 raise exceptions.InvalidLocation("This channel is not a ticket." 128 " If it is, use /register.") 129 if ticket.staff_note_thread is None: 130 raise exceptions.InvalidLocation("This ticket has no staff notes.") 131 thred = ctx.guild.get_thread( # type: ignore 132 ticket.staff_note_thread) 133 if thred is None: 134 raise exceptions.ReferenceNotFound("This ticket's staff notes thread is missing." 135 " Was it deleted?") 136 emd = discord.Embed(title="Success!", 137 description="You have joined the staff notes thread.", 138 color=discord.Color.green()) 139 await thred.add_user(ctx.user) 140 await ctx.followup.send(embed=emd, ephemeral=True) 141 142 @app_commands.command(name="anonymize", description="Toggle anonymous staff responses.") 143 @app_commands.guild_only() 144 @checks.is_staff_check() 145 async def anonymize(self, ctx: discord.Interaction) -> None: 146 """Toggle anonymous staff responses. 147 148 This command is used to toggle anonymous staff responses. 149 The implementation itself is in events.py. 150 151 Args: 152 ctx: The interaction context. 153 154 Raises: 155 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 156 Raised if the command is used in a channel that is not a ticket. 157 """ 158 await ctx.response.defer(ephemeral=True) 159 async with self._bt.get_connection() as confg: 160 # Checked by discord in decorator 161 ticket = await confg.fetch_ticket(ctx.channel.id) # type: ignore 162 if ticket is None: 163 raise exceptions.InvalidLocation("This channel is not a ticket.") 164 ticket.anonymous = not ticket.anonymous 165 status = ticket.anonymous 166 await confg.commit() 167 emd = discord.Embed(title="Success!", 168 description=f"Anonymous staff responses are now {status}.", 169 color=discord.Color.green() if status else discord.Color.red()) 170 await ctx.followup.send(embed=emd, ephemeral=True) 171 172 @app_commands.command(name="register", description="Register an existing channel as a ticket.") 173 @app_commands.describe(thread="The staff notes thread for the ticket.") 174 @app_commands.guild_only() 175 @checks.is_staff_check() 176 async def register(self, ctx: discord.Interaction, thread: discord.Thread | None = None) -> None: 177 """A migration command to register an existing channel as a ticket. 178 179 We have this command to allow users to migrate from the old version, 180 or add channels that the bot has missed while it was offline. 181 It basically just tells the bot to start tracking the channel. 182 183 Args: 184 ctx: The interaction context. 185 thread: The staff notes thread for the ticket. 186 187 Raises: 188 `tickets_plus.ext.exceptions.InvalidLocation`: Wrong location. 189 If the channel is already a ticket. 190 Or the execution space is not a text channel. 191 """ 192 await ctx.response.defer(ephemeral=True) 193 if isinstance(ctx.channel, discord.TextChannel): 194 channel = ctx.channel 195 async with self._bt.get_connection() as confg: 196 guild = await confg.get_guild(ctx.guild_id) # type: ignore # checked in decorator 197 if thread is None and guild.legacy_threads: 198 thread = await channel.create_thread( 199 name="Staff Notes", 200 reason=f"Staff notes for Ticket {channel.name}", 201 auto_archive_duration=10080, 202 ) 203 await thread.send(string.Template(guild.open_message).safe_substitute(channel=channel.mention)) 204 new, ticket = await confg.get_ticket( 205 ctx.channel.id, 206 ctx.guild_id, # type: ignore 207 thread.id) 208 # Unused, we just want to check if it's new and commit it. 209 del ticket 210 if not new: 211 raise exceptions.InvalidLocation("This channel is already a ticket.") 212 await confg.commit() 213 emd = discord.Embed(title="Success!", 214 description="Registered channel as a ticket.", 215 color=discord.Color.green()) 216 await ctx.followup.send(embed=emd, ephemeral=True) 217 return 218 raise exceptions.InvalidLocation("Invalid command execution space.") 219 220 @app_commands.command(name="usrstatus", description="Set a new user status.") 221 @app_commands.guild_only() 222 @checks.is_staff_check() 223 @app_commands.describe( 224 target="The user to set the status for.", 225 status="The new status.", 226 days="The new status time days.", 227 hours="The new status time hours.", 228 minutes="The new status time minutes.", 229 ) 230 @app_commands.choices(status=[ 231 app_commands.Choice(name="None", value=0), 232 app_commands.Choice(name="Support Blocked", value=1), 233 app_commands.Choice(name="Community Support Blocked", value=2), 234 ]) 235 async def usrstatus(self, 236 interaction: discord.Interaction, 237 target: discord.Member, 238 status: app_commands.Choice[int], 239 days: int = 0, 240 hours: int = 0, 241 minutes: int = 0) -> None: 242 """Set a new user status. 243 244 This command is used to set a new user status. 245 It's used to block users from opening tickets or from getting support. 246 247 Args: 248 interaction: Discord interaction. 249 target: The user to set the status for. 250 status: The new status. 251 days: The new status time days. 252 hours: The new status time hours. 253 minutes: The new status time minutes. 254 """ 255 await interaction.response.defer(ephemeral=True) 256 async with self._bt.get_connection() as confg: 257 member = await confg.get_member( 258 target.id, 259 interaction.guild_id # type: ignore 260 ) 261 member.status = status.value 262 if status.value == 0: 263 member.status_till = None 264 await confg.commit() 265 emd = discord.Embed(title="Success!", 266 description=f"Removed status from {target.mention}.", 267 color=discord.Color.green()) 268 emd2 = discord.Embed(title="Status Removed", 269 description=(f"Your status in {target.guild.name} has been removed" 270 f" by {interaction.user.display_name}."), 271 color=discord.Color.green()) 272 else: 273 if days + hours + minutes == 0: 274 penalty_time = "Indefinitely" 275 member.status_till = None 276 else: 277 penalty_time = datetime.timedelta(days=days, hours=hours, minutes=minutes) 278 member.status_till = utils.utcnow() + penalty_time 279 if status.value == 1: 280 if member.guild.support_block is None: 281 raise exceptions.InvalidParameters("The support block role has not been set.\n" 282 "This may be intentional.\n" 283 "If not please set it up using the /settings.") 284 await target.add_roles(discord.Object(member.guild.support_block)) 285 emd = discord.Embed(title="Success!", 286 description=(f"Blocked {target.mention} from opening tickets" 287 f" for {str(penalty_time)}."), 288 color=discord.Color.red()) 289 emd2 = discord.Embed(title="Support Blocked", 290 description=("You have been blocked from opening tickets from" 291 f" {target.guild.name} for {str(penalty_time)}."), 292 color=discord.Color.red()) 293 else: 294 if member.guild.helping_block is None: 295 raise exceptions.InvalidParameters("The helping block role has not been set.\n" 296 "This may be intentional.\n" 297 "If not please set it up using the /settings.") 298 await target.add_roles(discord.Object(member.guild.helping_block)) 299 emd = discord.Embed(title="Success!", 300 description=(f"Blocked {target.mention} " 301 f"from providing support for {str(penalty_time)}."), 302 color=discord.Color.red()) 303 emd2 = discord.Embed(title="Community Support Blocked", 304 description=("You have been blocked from providing " 305 f"support from {target.guild.name}" 306 f" for {str(penalty_time)}."), 307 color=discord.Color.red()) 308 if member.guild.strip_roles: 309 roles = await confg.get_all_community_roles(interaction.guild_id) # type: ignore 310 unpck = [discord.Object(rle.role_id) for rle in roles] 311 await target.remove_roles(*unpck, reason="Community Support Blocked") 312 await confg.commit() 313 await interaction.followup.send(embed=emd, ephemeral=True) 314 try: 315 await target.send(embed=emd2) 316 except discord.Forbidden: 317 logging.debug("Failed to send status message to user.")
Staff-only commands for Tickets+.
This cog contains all staff-only commands. These commands are only available to users with the staff role, and are used to manage the bot and the tickets.
StaffCmmd(bot_instance: tickets_plus.bot.TicketsPlusBot)
42 def __init__(self, bot_instance: bot.TicketsPlusBot) -> None: 43 """Initialises the cog instance. 44 45 We store some attributes here for later use. 46 47 Args: 48 bot_instance: The bot instance. 49 """ 50 self._bt = bot_instance 51 logging.info("Loaded %s", self.__class__.__name__)
Initialises the cog instance.
We store some attributes here for later use.
Arguments:
- bot_instance: The bot instance.
320async def setup(bot_instance: bot.TicketsPlusBot) -> None: 321 """Setup function for the StaffCmmd cog. 322 323 Adds the StaffCmmd cog to the bot. 324 Automatically called by the bot. 325 326 Args: 327 bot_instance: The bot instance. 328 """ 329 await bot_instance.add_cog(StaffCmmd(bot_instance))
Setup function for the StaffCmmd cog.
Adds the StaffCmmd cog to the bot. Automatically called by the bot.
Arguments:
- bot_instance: The bot instance.