Explorar el Código

More help command work

pull/13/head
Rocketsoup hace 2 meses
padre
commit
971fe0bdd2

+ 2
- 0
config.sample.py Ver fichero

46
 	'info_emoji': 'ℹ️',
46
 	'info_emoji': 'ℹ️',
47
 	# Logging something that happened on the server (e.g. a user joined the server)
47
 	# Logging something that happened on the server (e.g. a user joined the server)
48
 	'log_emoji': '📋',
48
 	'log_emoji': '📋',
49
+	# A task is in progress
50
+	'wait_emoji': '⏳',
49
 
51
 
50
     # -----------------------------------------------------------------------
52
     # -----------------------------------------------------------------------
51
     # Default values for cog-specific settings that a guild has not overridden
53
     # Default values for cog-specific settings that a guild has not overridden

+ 15
- 15
rocketbot/cogs/autokickcog.py Ver fichero

37
 		brief='autokick',
37
 		brief='autokick',
38
 		description='Whether this cog is enabled for a guild.')
38
 		description='Whether this cog is enabled for a guild.')
39
 	SETTING_BAN_COUNT = CogSetting('bancount', int,
39
 	SETTING_BAN_COUNT = CogSetting('bancount', int,
40
-			brief='number of repeat kicks before a ban',
41
-			description='The number of times a user can join and be kicked ' + \
42
-					'before the next rejoin will result in a ban. A value of 0 ' + \
40
+		brief='number of repeat kicks before a ban',
41
+		description='The number of times a user can join and be kicked '
42
+					'before the next rejoin will result in a ban. A value of 0 '
43
 					'disables this feature (only kick, never ban).',
43
 					'disables this feature (only kick, never ban).',
44
-			usage='<count:int>',
45
-			min_value=0)
44
+		usage='<count:int>',
45
+		min_value=0)
46
 	SETTING_OFFLINE_ONLY = CogSetting('offlineonly', bool,
46
 	SETTING_OFFLINE_ONLY = CogSetting('offlineonly', bool,
47
-			brief='whether to only kick users whose status is offline',
48
-			description='Compromised accounts may have a status of offline. ' + \
49
-					'If this setting is enabled, the user\'s status will be ' + \
50
-					'checked a few seconds after joining. If it is offline ' + \
47
+		brief='whether to only kick users whose status is offline',
48
+		description='Compromised accounts may have a status of offline. '
49
+					'If this setting is enabled, the user\'s status will be '
50
+					'checked a few seconds after joining. If it is offline '
51
 					'they will be kicked.',
51
 					'they will be kicked.',
52
-			usage='<true|false>')
52
+		usage='<true|false>')
53
 
53
 
54
 	STATE_KEY_RECENT_KICKS = "AutoKickCog.recent_joins"
54
 	STATE_KEY_RECENT_KICKS = "AutoKickCog.recent_joins"
55
 
55
 
129
 		else:
129
 		else:
130
 			await member.kick(reason='Rocketbot: Autokick enabled.')
130
 			await member.kick(reason='Rocketbot: Autokick enabled.')
131
 			msg = BotMessage(guild,
131
 			msg = BotMessage(guild,
132
-							text=f'Autokicked {member.mention} ({member.id}) ' + \
133
-								f'({AutoKickCog.ordinal(context.kick_count)} time). ' + \
134
-								disable_help + ' ' + ban_help,
135
-							type=BotMessage.TYPE_INFO,
136
-							context=None)
132
+				text=f'Autokicked {member.mention} ({member.id}) ' + \
133
+					f'({AutoKickCog.ordinal(context.kick_count)} time). ' + \
134
+					disable_help + ' ' + ban_help,
135
+				type=BotMessage.TYPE_INFO,
136
+				context=None)
137
 			await self.post_message(msg)
137
 			await self.post_message(msg)
138
 			self.log(guild, f'Autokicked {member.name} ' + \
138
 			self.log(guild, f'Autokicked {member.name} ' + \
139
 				f'({AutoKickCog.ordinal(context.kick_count)} time)')
139
 				f'({AutoKickCog.ordinal(context.kick_count)} time)')

+ 9
- 6
rocketbot/cogs/basecog.py Ver fichero

123
 
123
 
124
 	@classmethod
124
 	@classmethod
125
 	def get_guild_setting(cls,
125
 	def get_guild_setting(cls,
126
-			guild: Guild,
126
+			guild: Optional[Guild],
127
 			setting: CogSetting,
127
 			setting: CogSetting,
128
 			use_cog_default_if_not_set: bool = True):
128
 			use_cog_default_if_not_set: bool = True):
129
 		"""
129
 		"""
132
 		unless the optional `use_cog_default_if_not_set` is `False`, then
132
 		unless the optional `use_cog_default_if_not_set` is `False`, then
133
 		`None` will be returned.
133
 		`None` will be returned.
134
 		"""
134
 		"""
135
-		key = f'{cls.__name__}.{setting.name}'
136
-		value = Storage.get_config_value(guild, key)
137
-		if value is None and use_cog_default_if_not_set:
138
-			value = cls.get_cog_default(setting.name)
139
-		return value
135
+		if guild:
136
+			key = f'{cls.__name__}.{setting.name}'
137
+			value = Storage.get_config_value(guild, key)
138
+			if value is not None:
139
+				return value
140
+		if use_cog_default_if_not_set:
141
+			return cls.get_cog_default(setting.name)
142
+		return None
140
 
143
 
141
 	@classmethod
144
 	@classmethod
142
 	def set_guild_setting(cls,
145
 	def set_guild_setting(cls,

+ 35
- 18
rocketbot/cogs/generalcog.py Ver fichero

64
 			self.log(None, f'Session resumed after {disconnect_duration.total_seconds()} seconds')
64
 			self.log(None, f'Session resumed after {disconnect_duration.total_seconds()} seconds')
65
 
65
 
66
 	@command(
66
 	@command(
67
-		description='Posts a test warning',
67
+		description='Posts a test warning.',
68
 		extras={
68
 		extras={
69
-			'long_description': 'Tests whether a warning channel is configured for this ' + \
70
-				'guild by posting a test warning. If a mod mention is ' + \
71
-				'configured, that user/role will be tagged in the test warning.',
69
+			'long_description': 'Simulates a warning. The configured warning channel '
70
+								'and mod mention will be used.',
72
 		},
71
 		},
73
 	)
72
 	)
74
 	@guild_only()
73
 	@guild_only()
75
 	@default_permissions(ban_members=True)
74
 	@default_permissions(ban_members=True)
76
 	async def test_warn(self, interaction: Interaction):
75
 	async def test_warn(self, interaction: Interaction):
77
-		"""Command handler"""
78
 		if Storage.get_config_value(interaction.guild, ConfigKey.WARNING_CHANNEL_ID) is None:
76
 		if Storage.get_config_value(interaction.guild, ConfigKey.WARNING_CHANNEL_ID) is None:
79
 			await interaction.response.send_message(
77
 			await interaction.response.send_message(
80
 				f'{CONFIG["warning_emoji"]} No warning channel set!',
78
 				f'{CONFIG["warning_emoji"]} No warning channel set!',
92
 			)
90
 			)
93
 
91
 
94
 	@command(
92
 	@command(
95
-		description='Greets the user',
93
+		description='Greets the user.',
96
 		extras={
94
 		extras={
97
-			'long_description': 'Replies to the command message. Useful to ensure the ' + \
98
-				'bot is working properly.',
95
+			'long_description': 'Replies to the command message. Useful to ensure the '
96
+								'bot is responsive. Message is only visible to the user.',
99
 		},
97
 		},
100
 	)
98
 	)
101
 	async def hello(self, interaction: Interaction):
99
 	async def hello(self, interaction: Interaction):
106
 		)
104
 		)
107
 
105
 
108
 	@command(
106
 	@command(
109
-		description='Shuts down the bot',
107
+		description='Shuts down the bot.',
110
 		extras={
108
 		extras={
111
-			'long_description': 'Causes the bot script to terminate. Only usable by a ' + \
112
-				'user with server admin permissions.',
109
+			'long_description': 'Terminates the bot script. Only usable by a '
110
+								'server administrator.',
113
 		},
111
 		},
114
 	)
112
 	)
115
 	@guild_only()
113
 	@guild_only()
120
 		await self.bot.close()
118
 		await self.bot.close()
121
 
119
 
122
 	@command(
120
 	@command(
123
-		description='Mass deletes messages',
121
+		description='Mass deletes messages.',
124
 		extras={
122
 		extras={
125
 			'long_description': 'Deletes recent messages by the given user. The user ' +
123
 			'long_description': 'Deletes recent messages by the given user. The user ' +
126
 				'can be either an @ mention or a numeric user ID. The age is ' +
124
 				'can be either an @ mention or a numeric user ID. The age is ' +
132
 	@guild_only()
130
 	@guild_only()
133
 	@default_permissions(manage_messages=True)
131
 	@default_permissions(manage_messages=True)
134
 	async def delete_messages(self, interaction: Interaction, user: User, age: Transform[timedelta, TimeDeltaTransformer]) -> None:
132
 	async def delete_messages(self, interaction: Interaction, user: User, age: Transform[timedelta, TimeDeltaTransformer]) -> None:
135
-		"""Command handler"""
133
+		"""
134
+		Mass deletes messages.
135
+
136
+		Parameters
137
+		----------
138
+		interaction: :class:`Interaction`
139
+		user: :class:`User`
140
+			user to delete messages from
141
+		age: :class:`timedelta`
142
+			maximum age of messages to delete
143
+		"""
136
 		member_id = user.id
144
 		member_id = user.id
137
 		cutoff: datetime = datetime.now(timezone.utc) - age
145
 		cutoff: datetime = datetime.now(timezone.utc) - age
146
+
147
+		resp = await interaction.response.defer(ephemeral=True, thinking=True)
148
+
138
 		def predicate(message: Message) -> bool:
149
 		def predicate(message: Message) -> bool:
139
 			return str(message.author.id) == member_id and message.created_at >= cutoff
150
 			return str(message.author.id) == member_id and message.created_at >= cutoff
140
 		deleted_messages = []
151
 		deleted_messages = []
144
 			except DiscordException:
155
 			except DiscordException:
145
 				# XXX: Sloppily glossing over access errors instead of checking access
156
 				# XXX: Sloppily glossing over access errors instead of checking access
146
 				pass
157
 				pass
147
-		await interaction.response.send_message(
148
-			f'{CONFIG["success_emoji"]} Deleted {len(deleted_messages)} ' + \
149
-			f'messages by {user.mention}> from the past {describe_timedelta(age)}.',
150
-			ephemeral=True,
151
-		)
158
+
159
+		if len(deleted_messages) > 0:
160
+			await resp.resource.edit(
161
+				content=f'{CONFIG["success_emoji"]} Deleted {len(deleted_messages)} '
162
+						f'messages by {user.mention} from the past {describe_timedelta(age)}.',
163
+			)
164
+		else:
165
+			await resp.resource.edit(
166
+				content=f'{CONFIG["success_emoji"]} No messages found for {user.mention} '
167
+						'from the past {describe_timedelta(age)}.',
168
+			)

+ 31
- 12
rocketbot/cogs/helpcog.py Ver fichero

45
 			print(f'Subcommands for {cmd_name} was None')
45
 			print(f'Subcommands for {cmd_name} was None')
46
 			return []
46
 			return []
47
 		return [
47
 		return [
48
-			Choice(name=f'{subcmd_name} subcommand', value=f'subcmd:{cmd_name}.{subcmd_name}')
48
+			Choice(name=f'{subcmd_name} subcommand', value=f'subcmd:{cmd.name}.{subcmd_name}')
49
 			for subcmd_name in sorted(subcmds.keys())
49
 			for subcmd_name in sorted(subcmds.keys())
50
 			if len(current) == 0 or current in subcmd_name
50
 			if len(current) == 0 or current in subcmd_name
51
 		][:25]
51
 		][:25]
137
 			add_text_to_index(cog, cog.qualified_name)
137
 			add_text_to_index(cog, cog.qualified_name)
138
 			if cog.description:
138
 			if cog.description:
139
 				add_text_to_index(cog, cog.description)
139
 				add_text_to_index(cog, cog.description)
140
-		print(self.obj_index.keys())
141
-		print(self.keyword_index.keys())
142
 
140
 
143
 	def object_for_help_symbol(self, symbol: str) -> Optional[Union[Command, Group, BaseCog]]:
141
 	def object_for_help_symbol(self, symbol: str) -> Optional[Union[Command, Group, BaseCog]]:
144
 		self.__create_help_index()
142
 		self.__create_help_index()
167
 		----------
165
 		----------
168
 		interaction: Interaction
166
 		interaction: Interaction
169
 		topic: Optional[str]
167
 		topic: Optional[str]
170
-			Optional topic to get specific help for. Getting help on a command can optionally start with a leading slash.
168
+			optional command, module, or keywords to get specific help for
171
 		subtopic: Optional[str]
169
 		subtopic: Optional[str]
172
-			Optional subtopic to get specific help for.
170
+			optional subcommand to get specific help for
173
 		"""
171
 		"""
174
 		print(f'help_command(interaction, {topic}, {subtopic})')
172
 		print(f'help_command(interaction, {topic}, {subtopic})')
175
 
173
 
316
 		)
314
 		)
317
 
315
 
318
 	async def __send_command_help(self, interaction: Interaction, command_or_group: Union[Command, Group], addendum: Optional[str] = None) -> None:
316
 	async def __send_command_help(self, interaction: Interaction, command_or_group: Union[Command, Group], addendum: Optional[str] = None) -> None:
317
+		if isinstance(command_or_group, Command):
318
+			print(f"Doc:\n{command_or_group.callback.__doc__}")
319
 		text = ''
319
 		text = ''
320
 		if addendum is not None:
320
 		if addendum is not None:
321
 			text += addendum + '\n\n'
321
 			text += addendum + '\n\n'
323
 		if isinstance(command_or_group, Group):
323
 		if isinstance(command_or_group, Group):
324
 			subcmds: dict[str, Command] = self.get_subcommand_list(command_or_group, permissions=interaction.permissions)
324
 			subcmds: dict[str, Command] = self.get_subcommand_list(command_or_group, permissions=interaction.permissions)
325
 			if len(subcmds) > 0:
325
 			if len(subcmds) > 0:
326
-				text += '\n\n### Subcommands:'
326
+				text += '\n### Subcommands:'
327
 				for subcmd_name, subcmd in sorted(subcmds.items()):
327
 				for subcmd_name, subcmd in sorted(subcmds.items()):
328
 					text += f'\n- `{subcmd_name}`: {subcmd.description}'
328
 					text += f'\n- `{subcmd_name}`: {subcmd.description}'
329
 		else:
329
 		else:
330
 			params = command_or_group.parameters
330
 			params = command_or_group.parameters
331
 			if len(params) > 0:
331
 			if len(params) > 0:
332
-				text += '\n\n### Parameters:'
332
+				text += '\n### Parameters:'
333
 				for param in params:
333
 				for param in params:
334
 					text += f'\n- `{param.name}`: {param.description}'
334
 					text += f'\n- `{param.name}`: {param.description}'
335
 		await interaction.response.send_message(text, ephemeral=True)
335
 		await interaction.response.send_message(text, ephemeral=True)
336
 
336
 
337
 	async def __send_subcommand_help(self, interaction: Interaction, group: Group, subcommand: Command) -> None:
337
 	async def __send_subcommand_help(self, interaction: Interaction, group: Group, subcommand: Command) -> None:
338
-		text = f'## :information_source: Subcommand Help\n`/{group.name} {subcommand.name}`\n\n{subcommand.description}\n\n{subcommand.description}'
338
+		text = f'## :information_source: Subcommand Help'
339
+		text += f'\n`/{group.name} {subcommand.name}`'
340
+		text += f'\n\n{subcommand.description}'
339
 		params = subcommand.parameters
341
 		params = subcommand.parameters
340
 		if len(params) > 0:
342
 		if len(params) > 0:
341
-			text += '\n\n### Parameters:'
343
+			text += '\n### Parameters:'
342
 			for param in params:
344
 			for param in params:
343
 				text += f'\n- `{param.name}`: {param.description}'
345
 				text += f'\n- `{param.name}`: {param.description}'
344
 		await interaction.response.send_message(text, ephemeral=True)
346
 		await interaction.response.send_message(text, ephemeral=True)
345
 
347
 
346
 	async def __send_cog_help(self, interaction: Interaction, cog: BaseCog) -> None:
348
 	async def __send_cog_help(self, interaction: Interaction, cog: BaseCog) -> None:
347
-		text = f'## :information_source: Module Help\n{cog.qualified_name}'
349
+		text = f'## :information_source: Module Help'
350
+		text += f'\n**{cog.qualified_name}** module'
348
 		if cog.description is not None:
351
 		if cog.description is not None:
349
-			text += f'\n{cog.description}'
352
+			text += f'\n\n{cog.description}'
353
+
354
+		cmds = [
355
+			cmd
356
+			for cmd in sorted(cog.get_app_commands(), key=lambda c: c.name)
357
+			if can_use_command(cmd, interaction.permissions)
358
+		]
359
+		if len(cmds) > 0:
360
+			text += '\n### Commands:'
361
+			for cmd in cmds:
362
+				text += f'\n- `/{cmd.name}` - {cmd.description}'
363
+				if isinstance(cmd, Group):
364
+					subcmds = [ subcmd for subcmd in cmd.commands if can_use_command(subcmd, interaction.permissions) ]
365
+					if len(subcmds) > 0:
366
+						text += f' ({len(subcmds)} subcommands)'
367
+
350
 		settings = cog.settings
368
 		settings = cog.settings
351
 		if len(settings) > 0:
369
 		if len(settings) > 0:
352
 			text += '\n### Configuration'
370
 			text += '\n### Configuration'
356
 			for setting in sorted(settings, key=lambda s: s.name):
374
 			for setting in sorted(settings, key=lambda s: s.name):
357
 				if setting.name == 'enabled':
375
 				if setting.name == 'enabled':
358
 					continue
376
 					continue
359
-				text += f'\n- `/get` or `/set {cog.config_prefix}_{setting.name}` - {setting.description}'
377
+				text += f'\n- `/get` or `/set {cog.config_prefix}_{setting.name}` - {setting.brief}'
378
+		print(text)
360
 		await interaction.response.send_message(
379
 		await interaction.response.send_message(
361
 			text,
380
 			text,
362
 			ephemeral=True,
381
 			ephemeral=True,

+ 6
- 6
rocketbot/cogs/urlspamcog.py Ver fichero

38
 			enum_values={'nothing', 'modwarn', 'delete', 'kick', 'ban'})
38
 			enum_values={'nothing', 'modwarn', 'delete', 'kick', 'ban'})
39
 	SETTING_JOIN_AGE = CogSetting('joinage', timedelta,
39
 	SETTING_JOIN_AGE = CogSetting('joinage', timedelta,
40
 			brief='seconds since member joined',
40
 			brief='seconds since member joined',
41
-			description='The minimum seconds since the user joined the ' + \
42
-				'server before they can post URLs. URLs posted by users ' + \
43
-				'who joined too recently will be flagged. Keep in mind ' + \
44
-				'many servers have a minimum 10 minute cooldown before ' + \
45
-				'new members can say anything. Setting to 0 effectively ' + \
41
+			description='The minimum seconds since the user joined the '
42
+				'server before they can post URLs. URLs posted by users '
43
+				'who joined too recently will be flagged. Keep in mind '
44
+				'many servers have a minimum 10 minute cooldown before '
45
+				'new members can say anything. Setting to 0 effectively '
46
 				'disables URL spam detection.',
46
 				'disables URL spam detection.',
47
 			usage='<seconds:int>',
47
 			usage='<seconds:int>',
48
 			min_value=timedelta(seconds=0))
48
 			min_value=timedelta(seconds=0))
49
 	SETTING_DECEPTIVE_ACTION = CogSetting('deceptiveaction', Literal['nothing', 'modwarn', 'modwarndelete', 'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'],
49
 	SETTING_DECEPTIVE_ACTION = CogSetting('deceptiveaction', Literal['nothing', 'modwarn', 'modwarndelete', 'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'],
50
 			brief='action to take on deceptive link markdown',
50
 			brief='action to take on deceptive link markdown',
51
-			description='The action to take on chat messages with links ' + \
51
+			description='The action to take on chat messages with links '
52
 				'where the text looks like a different URL than the actual link.',
52
 				'where the text looks like a different URL than the actual link.',
53
 			enum_values={'nothing', 'modwarn', 'modwarndelete',
53
 			enum_values={'nothing', 'modwarn', 'modwarndelete',
54
 				'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'})
54
 				'chatwarn', 'chatwarndelete', 'delete', 'kick', 'ban'})

+ 27
- 11
rocketbot/cogs/usernamecog.py Ver fichero

88
 	)
88
 	)
89
 
89
 
90
 	@username.command(
90
 	@username.command(
91
-		description='Adds a username pattern',
91
+		description='Adds a username pattern to match against new members.',
92
 		extras={
92
 		extras={
93
 			'long_description': 'Adds a username pattern.',
93
 			'long_description': 'Adds a username pattern.',
94
 			'usage': '<pattern>',
94
 			'usage': '<pattern>',
95
 		},
95
 		},
96
 	)
96
 	)
97
 	async def add(self, interaction: Interaction, pattern: str) -> None:
97
 	async def add(self, interaction: Interaction, pattern: str) -> None:
98
-		"""Command handler"""
98
+		"""
99
+		Adds a username pattern to match against new members.
100
+
101
+		Parameters
102
+		----------
103
+		interaction : Interaction
104
+		pattern : str
105
+			a substring to look for in usernames
106
+		"""
99
 		norm_pattern = pattern.lower()
107
 		norm_pattern = pattern.lower()
100
 		patterns: list[str] = self.__get_patterns(interaction.guild)
108
 		patterns: list[str] = self.__get_patterns(interaction.guild)
101
 		if norm_pattern in patterns:
109
 		if norm_pattern in patterns:
102
 			await interaction.response.send_message(
110
 			await interaction.response.send_message(
103
-				f'Pattern `{norm_pattern}` already added.',
111
+				f'{CONFIG["warning_emoji"]} Pattern `{norm_pattern}` already added.',
104
 				ephemeral=True
112
 				ephemeral=True
105
 			)
113
 			)
106
 			return
114
 			return
107
 		patterns.append(norm_pattern)
115
 		patterns.append(norm_pattern)
108
 		self.__save_patterns(interaction.guild, patterns)
116
 		self.__save_patterns(interaction.guild, patterns)
109
 		await interaction.response.send_message(
117
 		await interaction.response.send_message(
110
-			f'Pattern `{norm_pattern}` added.',
118
+			f'{CONFIG["success_emoji"]} Pattern `{norm_pattern}` added.',
111
 			ephemeral=True
119
 			ephemeral=True
112
 		)
120
 		)
113
 
121
 
114
 	@username.command(
122
 	@username.command(
115
-		description='Removes a username pattern',
123
+		description='Removes a username pattern.',
116
 		extras={
124
 		extras={
117
 			'long_description': 'Removes an existing username pattern',
125
 			'long_description': 'Removes an existing username pattern',
118
 			'usage': '<pattern>',
126
 			'usage': '<pattern>',
119
 		},
127
 		},
120
 	)
128
 	)
121
 	async def remove(self, interaction: Interaction, pattern: str) -> None:
129
 	async def remove(self, interaction: Interaction, pattern: str) -> None:
122
-		"""Command handler"""
130
+		"""
131
+		Removes a username pattern.
132
+
133
+		Parameters
134
+		----------
135
+		interaction : Interaction
136
+		pattern : str
137
+		    the existing username pattern to remove
138
+		"""
123
 		norm_pattern = pattern.lower()
139
 		norm_pattern = pattern.lower()
124
 		guild: Guild = interaction.guild
140
 		guild: Guild = interaction.guild
125
 		patterns: list[str] = self.__get_patterns(guild)
141
 		patterns: list[str] = self.__get_patterns(guild)
127
 		patterns = list(filter(lambda p: p != norm_pattern, patterns))
143
 		patterns = list(filter(lambda p: p != norm_pattern, patterns))
128
 		if len(patterns) == len_before:
144
 		if len(patterns) == len_before:
129
 			await interaction.response.send_message(
145
 			await interaction.response.send_message(
130
-				f'Pattern `{norm_pattern}` not found.',
146
+				f'{CONFIG["warning_emoji"]} Pattern `{norm_pattern}` not found.',
131
 				ephemeral=True,
147
 				ephemeral=True,
132
 			)
148
 			)
133
 			return
149
 			return
134
 		self.__save_patterns(guild, patterns)
150
 		self.__save_patterns(guild, patterns)
135
 		await interaction.response.send_message(
151
 		await interaction.response.send_message(
136
-			f'Pattern `{norm_pattern}` removed.',
152
+			f'{CONFIG["success_emoji"]} Pattern `{norm_pattern}` removed.',
137
 			ephemeral=True,
153
 			ephemeral=True,
138
 		)
154
 		)
139
 
155
 
140
 	@username.command(
156
 	@username.command(
141
-		description='Lists username patterns'
157
+		description='Lists existing username patterns.'
142
 	)
158
 	)
143
 	async def list(self, interaction: Interaction) -> None:
159
 	async def list(self, interaction: Interaction) -> None:
144
 		"""Command handler"""
160
 		"""Command handler"""
146
 		patterns: list[str] = self.__get_patterns(guild)
162
 		patterns: list[str] = self.__get_patterns(guild)
147
 		if len(patterns) == 0:
163
 		if len(patterns) == 0:
148
 			await interaction.response.send_message(
164
 			await interaction.response.send_message(
149
-				'No patterns defined',
165
+				f'{CONFIG["success_emoji"]} No patterns defined.',
150
 				ephemeral=True,
166
 				ephemeral=True,
151
 			)
167
 			)
152
 		else:
168
 		else:
153
-			msg = 'Patterns:\n\n> `' + '`\n> `'.join(patterns) + '`'
169
+			msg = f'{CONFIG["info_emoji"]} Patterns:\n\n> `' + '`\n> `'.join(patterns) + '`'
154
 			await interaction.response.send_message(
170
 			await interaction.response.send_message(
155
 				msg,
171
 				msg,
156
 				ephemeral=True,
172
 				ephemeral=True,

Loading…
Cancelar
Guardar