0
# Commands Framework
1
2
A comprehensive prefix-based command system built on top of the core Discord.py client. The commands framework provides command parsing, argument conversion, permission checks, cooldowns, error handling, and modular organization through cogs.
3
4
## Capabilities
5
6
### Bot Classes
7
8
Command bots extend the base client with command processing capabilities and customizable prefix handling.
9
10
```python { .api }
11
class Bot(commands.Bot):
12
"""
13
Bot client with command processing capabilities.
14
15
Parameters:
16
- command_prefix: String or callable returning command prefix(es)
17
- help_command: Help command instance (None to disable)
18
- description: Bot description for help
19
- intents: Gateway intents
20
- case_insensitive: Whether commands are case insensitive
21
- strip_after_prefix: Whether to strip whitespace after prefix
22
"""
23
def __init__(
24
self,
25
command_prefix: Union[str, List[str], Callable],
26
*,
27
help_command: Optional[HelpCommand] = ...,
28
description: str = None,
29
intents: Intents,
30
case_insensitive: bool = False,
31
strip_after_prefix: bool = False,
32
**options
33
): ...
34
35
# Command registration
36
def command(self, name: str = None, **attrs) -> Callable:
37
"""Decorator to register a command."""
38
39
def group(self, name: str = None, **attrs) -> Callable:
40
"""Decorator to register a command group."""
41
42
def check(self, predicate: Callable) -> Callable:
43
"""Decorator to add a global check."""
44
45
def before_invoke(self, coro: Callable) -> Callable:
46
"""Decorator for global before-invoke hook."""
47
48
def after_invoke(self, coro: Callable) -> Callable:
49
"""Decorator for global after-invoke hook."""
50
51
# Command management
52
def add_command(self, command: Command) -> None:
53
"""Add a command to the bot."""
54
55
def remove_command(self, name: str) -> Optional[Command]:
56
"""Remove a command from the bot."""
57
58
def get_command(self, name: str) -> Optional[Command]:
59
"""Get a command by name."""
60
61
# Cog management
62
async def add_cog(self, cog: Cog) -> None:
63
"""Add a cog to the bot."""
64
65
async def remove_cog(self, name: str) -> Optional[Cog]:
66
"""Remove a cog from the bot."""
67
68
def get_cog(self, name: str) -> Optional[Cog]:
69
"""Get a cog by name."""
70
71
# Command processing
72
async def get_prefix(self, message: Message) -> List[str]:
73
"""Get valid prefixes for a message."""
74
75
async def get_context(self, message: Message, *, cls: Type = Context) -> Context:
76
"""Get command context for a message."""
77
78
async def invoke(self, ctx: Context) -> None:
79
"""Invoke a command from context."""
80
81
async def process_commands(self, message: Message) -> None:
82
"""Process message for commands."""
83
84
# Properties
85
commands: Set[Command] # All registered commands
86
cogs: Dict[str, Cog] # All loaded cogs
87
extensions: Dict[str, types.ModuleType] # Loaded extensions
88
89
class AutoShardedBot(Bot):
90
"""
91
Bot with automatic sharding capabilities.
92
"""
93
def __init__(self, command_prefix, **kwargs): ...
94
95
shard_count: Optional[int] # Number of shards
96
shards: Dict[int, ShardInfo] # Shard information
97
98
# Prefix helpers
99
def when_mentioned(bot: Bot, message: Message) -> List[str]:
100
"""Return bot mention as prefix."""
101
102
def when_mentioned_or(*prefixes: str) -> Callable:
103
"""Return bot mention or specified prefixes."""
104
```
105
106
### Command Context
107
108
Context objects provide information about command invocation including the message, channel, guild, and author.
109
110
```python { .api }
111
class Context:
112
"""
113
Command invocation context containing message and environment info.
114
"""
115
message: Message # Message that triggered the command
116
bot: Bot # Bot instance
117
args: List[Any] # Parsed command arguments
118
kwargs: Dict[str, Any] # Parsed keyword arguments
119
prefix: str # Prefix used to invoke command
120
command: Optional[Command] # Command being invoked
121
invoked_with: Optional[str] # String used to invoke command
122
invoked_parents: List[str] # Parent command names for subcommands
123
invoked_subcommand: Optional[Command] # Subcommand being invoked
124
subcommand_passed: Optional[str] # String passed for subcommand
125
command_failed: bool # Whether command failed
126
127
# Shortcuts to message properties
128
author: Union[User, Member] # Command author
129
guild: Optional[Guild] # Guild if invoked in guild
130
channel: Union[TextChannel, DMChannel, GroupChannel] # Channel
131
me: Union[ClientUser, Member] # Bot user/member
132
voice_client: Optional[VoiceClient] # Voice client if connected
133
134
# Utility methods
135
async def send(
136
self,
137
content: str = None,
138
*,
139
embed: Embed = None,
140
embeds: List[Embed] = None,
141
file: File = None,
142
files: List[File] = None,
143
view: View = None,
144
ephemeral: bool = False,
145
reference: MessageReference = None,
146
**kwargs
147
) -> Message:
148
"""Send a message to the context channel."""
149
150
async def reply(self, content: str = None, **kwargs) -> Message:
151
"""Reply to the context message."""
152
153
def typing(self) -> Typing:
154
"""Return typing context manager."""
155
156
async def invoke(self, command: Command, *args, **kwargs) -> Any:
157
"""Invoke another command."""
158
159
async def reinvoke(self, *, call_hooks: bool = False, restart: bool = True) -> None:
160
"""Re-invoke the current command."""
161
162
def valid(self) -> bool:
163
"""Check if context is valid for command invocation."""
164
165
@property
166
def clean_prefix(self) -> str:
167
"""Prefix with bot mention resolved to nickname."""
168
169
@property
170
def cog(self) -> Optional[Cog]:
171
"""Cog that contains the command."""
172
```
173
174
### Commands & Groups
175
176
Command objects represent individual bot commands with argument parsing, checks, and execution logic.
177
178
```python { .api }
179
class Command:
180
"""
181
Represents a bot command.
182
"""
183
def __init__(self, func: Callable, **kwargs): ...
184
185
name: str # Command name
186
callback: Callable # Command function
187
help: Optional[str] # Help text
188
brief: Optional[str] # Brief description
189
usage: Optional[str] # Usage string
190
aliases: List[str] # Command aliases
191
enabled: bool # Whether command is enabled
192
hidden: bool # Whether command is hidden from help
193
checks: List[Callable] # Command checks
194
description: str # Long description
195
signature: str # Command signature with parameters
196
qualified_name: str # Full command name including parents
197
parents: List[Group] # Parent command groups
198
cog: Optional[Cog] # Cog containing this command
199
params: Dict[str, inspect.Parameter] # Command parameters
200
201
async def __call__(self, context: Context, *args, **kwargs) -> Any:
202
"""Invoke the command."""
203
204
async def invoke(self, context: Context, *args, **kwargs) -> Any:
205
"""Invoke the command with context."""
206
207
async def reinvoke(self, context: Context, *, call_hooks: bool = False) -> None:
208
"""Re-invoke the command."""
209
210
def error(self, coro: Callable) -> Callable:
211
"""Decorator for command error handler."""
212
213
def before_invoke(self, coro: Callable) -> Callable:
214
"""Decorator for before-invoke hook."""
215
216
def after_invoke(self, coro: Callable) -> Callable:
217
"""Decorator for after-invoke hook."""
218
219
def add_check(self, func: Callable) -> None:
220
"""Add a check to the command."""
221
222
def remove_check(self, func: Callable) -> bool:
223
"""Remove a check from the command."""
224
225
def copy(self) -> Command:
226
"""Create a copy of the command."""
227
228
class Group(Command):
229
"""
230
Command that can contain subcommands.
231
"""
232
def __init__(self, **attrs): ...
233
234
commands: Set[Command] # Subcommands
235
invoke_without_subcommand: bool # Whether to invoke if no subcommand
236
case_insensitive: bool # Case insensitive subcommand matching
237
238
def command(self, *args, **kwargs) -> Callable:
239
"""Decorator to add a subcommand."""
240
241
def group(self, *args, **kwargs) -> Callable:
242
"""Decorator to add a subcommand group."""
243
244
def add_command(self, command: Command) -> None:
245
"""Add a subcommand."""
246
247
def remove_command(self, name: str) -> Optional[Command]:
248
"""Remove a subcommand."""
249
250
def get_command(self, name: str) -> Optional[Command]:
251
"""Get a subcommand by name."""
252
253
def walk_commands(self) -> Iterator[Command]:
254
"""Recursively walk all commands."""
255
256
# Command decorators
257
def command(name: str = None, **attrs) -> Callable:
258
"""Decorator to create a command."""
259
260
def group(name: str = None, **attrs) -> Callable:
261
"""Decorator to create a command group."""
262
```
263
264
### Cogs
265
266
Cogs provide modular organization for commands, event listeners, and shared functionality.
267
268
```python { .api }
269
class Cog:
270
"""
271
Base class for command cogs (modules).
272
"""
273
def __init_subclass__(cls, **kwargs): ...
274
275
qualified_name: str # Cog name
276
description: Optional[str] # Cog description
277
278
def get_commands(self) -> List[Command]:
279
"""Get all commands in this cog."""
280
281
def walk_commands(self) -> Iterator[Command]:
282
"""Recursively walk all commands in this cog."""
283
284
def get_listeners(self) -> List[Tuple[str, Callable]]:
285
"""Get all event listeners in this cog."""
286
287
# Lifecycle hooks
288
async def cog_load(self) -> None:
289
"""Called when cog is loaded."""
290
291
async def cog_unload(self) -> None:
292
"""Called when cog is unloaded."""
293
294
def cog_check(self, ctx: Context) -> bool:
295
"""Global check for all commands in this cog."""
296
297
async def cog_command_error(self, ctx: Context, error: Exception) -> None:
298
"""Error handler for all commands in this cog."""
299
300
async def cog_before_invoke(self, ctx: Context) -> None:
301
"""Before-invoke hook for all commands in this cog."""
302
303
async def cog_after_invoke(self, ctx: Context) -> None:
304
"""After-invoke hook for all commands in this cog."""
305
306
class GroupCog(Cog):
307
"""
308
Cog that acts as a command group.
309
"""
310
group_name: str # Name of the group
311
group_description: str # Description of the group
312
313
# Inherits Group functionality for subcommands
314
```
315
316
### Argument Conversion
317
318
Converters transform string arguments into Python objects with built-in support for Discord entities and custom conversion logic.
319
320
```python { .api }
321
class Converter:
322
"""
323
Base class for argument converters.
324
"""
325
async def convert(self, ctx: Context, argument: str) -> Any:
326
"""Convert string argument to desired type."""
327
raise NotImplementedError
328
329
# Built-in converters
330
class MemberConverter(Converter):
331
"""Convert to Member object via ID, mention, or name."""
332
async def convert(self, ctx: Context, argument: str) -> Member: ...
333
334
class UserConverter(Converter):
335
"""Convert to User object via ID, mention, or name."""
336
async def convert(self, ctx: Context, argument: str) -> User: ...
337
338
class TextChannelConverter(Converter):
339
"""Convert to TextChannel via ID, mention, or name."""
340
async def convert(self, ctx: Context, argument: str) -> TextChannel: ...
341
342
class VoiceChannelConverter(Converter):
343
"""Convert to VoiceChannel via ID, mention, or name."""
344
async def convert(self, ctx: Context, argument: str) -> VoiceChannel: ...
345
346
class CategoryChannelConverter(Converter):
347
"""Convert to CategoryChannel via ID or name."""
348
async def convert(self, ctx: Context, argument: str) -> CategoryChannel: ...
349
350
class RoleConverter(Converter):
351
"""Convert to Role via ID, mention, or name."""
352
async def convert(self, ctx: Context, argument: str) -> Role: ...
353
354
class GuildConverter(Converter):
355
"""Convert to Guild via ID or name."""
356
async def convert(self, ctx: Context, argument: str) -> Guild: ...
357
358
class EmojiConverter(Converter):
359
"""Convert to Emoji via ID, mention, or name."""
360
async def convert(self, ctx: Context, argument: str) -> Emoji: ...
361
362
class PartialEmojiConverter(Converter):
363
"""Convert to PartialEmoji via ID, mention, name, or unicode."""
364
async def convert(self, ctx: Context, argument: str) -> PartialEmoji: ...
365
366
class MessageConverter(Converter):
367
"""Convert to Message via ID or message link."""
368
async def convert(self, ctx: Context, argument: str) -> Message: ...
369
370
class InviteConverter(Converter):
371
"""Convert to Invite via invite code or URL."""
372
async def convert(self, ctx: Context, argument: str) -> Invite: ...
373
374
class ColourConverter(Converter):
375
"""Convert to Colour via hex, RGB, or name."""
376
async def convert(self, ctx: Context, argument: str) -> Colour: ...
377
378
ColorConverter = ColourConverter # Alias
379
380
class clean_content(Converter):
381
"""
382
Convert message content with mentions resolved.
383
384
Parameters:
385
- fix_channel_mentions: Whether to fix channel mentions
386
- use_nicknames: Whether to use nicknames for users
387
- escape_markdown: Whether to escape markdown
388
- remove_markdown: Whether to remove markdown
389
"""
390
def __init__(
391
self,
392
*,
393
fix_channel_mentions: bool = False,
394
use_nicknames: bool = True,
395
escape_markdown: bool = False,
396
remove_markdown: bool = False
397
): ...
398
399
class Greedy:
400
"""
401
Converter that consumes multiple arguments.
402
403
Usage: async def command(ctx, users: commands.Greedy[Member]):
404
"""
405
def __init__(self, converter: Type): ...
406
407
class Range:
408
"""
409
Converter that validates numeric ranges.
410
411
Parameters:
412
- min: Minimum value (inclusive)
413
- max: Maximum value (inclusive)
414
415
Usage: async def command(ctx, number: commands.Range[int, 1, 10]):
416
"""
417
def __init__(self, annotation: Type, min: Any = None, max: Any = None): ...
418
419
# Converter utilities
420
async def run_converters(ctx: Context, converter: Type, argument: str, param: inspect.Parameter) -> Any:
421
"""Run converter on argument."""
422
```
423
424
### Command Checks
425
426
Checks provide permission and condition validation before command execution.
427
428
```python { .api }
429
# Check decorators
430
def check(predicate: Callable[[Context], bool]) -> Callable:
431
"""Add a check to a command."""
432
433
def check_any(*checks: Callable) -> Callable:
434
"""Require any of the provided checks to pass."""
435
436
# Permission checks
437
def has_role(item: Union[int, str]) -> Callable:
438
"""Check if user has a specific role."""
439
440
def has_any_role(*items: Union[int, str]) -> Callable:
441
"""Check if user has any of the specified roles."""
442
443
def has_permissions(**perms: bool) -> Callable:
444
"""Check if user has specific permissions."""
445
446
def has_guild_permissions(**perms: bool) -> Callable:
447
"""Check if user has specific guild permissions."""
448
449
def bot_has_role(item: Union[int, str]) -> Callable:
450
"""Check if bot has a specific role."""
451
452
def bot_has_any_role(*items: Union[int, str]) -> Callable:
453
"""Check if bot has any of the specified roles."""
454
455
def bot_has_permissions(**perms: bool) -> Callable:
456
"""Check if bot has specific permissions."""
457
458
def bot_has_guild_permissions(**perms: bool) -> Callable:
459
"""Check if bot has specific guild permissions."""
460
461
# Context checks
462
def dm_only() -> Callable:
463
"""Command can only be used in DMs."""
464
465
def guild_only() -> Callable:
466
"""Command can only be used in guilds."""
467
468
def is_owner() -> Callable:
469
"""Check if user is bot owner."""
470
471
def is_nsfw() -> Callable:
472
"""Check if channel is NSFW."""
473
474
# Hook decorators
475
def before_invoke(coro: Callable) -> Callable:
476
"""Register before-invoke hook."""
477
478
def after_invoke(coro: Callable) -> Callable:
479
"""Register after-invoke hook."""
480
```
481
482
### Cooldowns & Rate Limiting
483
484
Cooldown system prevents command spam and implements various rate limiting strategies.
485
486
```python { .api }
487
class BucketType(Enum):
488
"""Cooldown bucket types."""
489
default = 0 # Global cooldown
490
user = 1 # Per-user cooldown
491
guild = 2 # Per-guild cooldown
492
channel = 3 # Per-channel cooldown
493
member = 4 # Per-member (user+guild) cooldown
494
category = 5 # Per-category cooldown
495
role = 6 # Per-role cooldown
496
497
class Cooldown:
498
"""
499
Represents a command cooldown.
500
501
Parameters:
502
- rate: Number of times command can be used
503
- per: Time period in seconds
504
"""
505
def __init__(self, rate: int, per: float): ...
506
507
rate: int # Number of uses allowed
508
per: float # Time period in seconds
509
510
def get_tokens(self, current: float = None) -> int:
511
"""Get available tokens."""
512
513
def update_rate_limit(self, current: float = None) -> Optional[float]:
514
"""Update rate limit and return retry after time."""
515
516
def reset(self) -> None:
517
"""Reset the cooldown."""
518
519
def copy(self) -> Cooldown:
520
"""Create a copy of the cooldown."""
521
522
class CooldownMapping:
523
"""Maps cooldown buckets to cooldown instances."""
524
def __init__(self, original: Cooldown, type: BucketType): ...
525
526
def copy(self) -> CooldownMapping:
527
"""Create a copy of the mapping."""
528
529
def get_bucket(self, message: Message, current: float = None) -> Cooldown:
530
"""Get cooldown bucket for message."""
531
532
def update_rate_limit(self, message: Message, current: float = None) -> Optional[float]:
533
"""Update rate limit for message."""
534
535
class DynamicCooldownMapping(CooldownMapping):
536
"""Cooldown mapping with dynamic cooldown function."""
537
def __init__(self, cooldown_func: Callable[[Message], Cooldown], type: BucketType): ...
538
539
class MaxConcurrency:
540
"""
541
Limit concurrent command executions.
542
543
Parameters:
544
- number: Maximum concurrent executions
545
- per: Bucket type for concurrency limit
546
- wait: Whether to wait for slot availability
547
"""
548
def __init__(self, number: int, *, per: BucketType, wait: bool = False): ...
549
550
# Cooldown decorators
551
def cooldown(rate: int, per: float, type: BucketType = BucketType.default) -> Callable:
552
"""Add a cooldown to a command."""
553
554
def dynamic_cooldown(cooldown: Callable[[Message], Cooldown], type: BucketType = BucketType.default) -> Callable:
555
"""Add a dynamic cooldown to a command."""
556
557
def max_concurrency(number: int, *, per: BucketType = BucketType.default, wait: bool = False) -> Callable:
558
"""Limit concurrent command executions."""
559
```
560
561
### Error Handling
562
563
Comprehensive error handling for commands with specific exception types for different failure scenarios.
564
565
```python { .api }
566
# Base command errors
567
class CommandError(DiscordException):
568
"""Base exception for command errors."""
569
pass
570
571
class UserInputError(CommandError):
572
"""Base exception for user input errors."""
573
pass
574
575
class CommandNotFound(CommandError):
576
"""Command was not found."""
577
pass
578
579
class DisabledCommand(CommandError):
580
"""Command is disabled."""
581
pass
582
583
class CommandInvokeError(CommandError):
584
"""Exception occurred during command execution."""
585
def __init__(self, e: Exception): ...
586
original: Exception
587
588
# Argument errors
589
class MissingRequiredArgument(UserInputError):
590
"""Required argument is missing."""
591
def __init__(self, param: inspect.Parameter): ...
592
param: inspect.Parameter
593
594
class TooManyArguments(UserInputError):
595
"""Too many arguments provided."""
596
pass
597
598
class BadArgument(UserInputError):
599
"""Argument could not be converted."""
600
pass
601
602
class BadUnionArgument(UserInputError):
603
"""Union argument could not be converted."""
604
def __init__(self, param: inspect.Parameter, converters: List[Type], errors: List[CommandError]): ...
605
param: inspect.Parameter
606
converters: List[Type]
607
errors: List[CommandError]
608
609
class BadLiteralArgument(UserInputError):
610
"""Literal argument is not one of the valid choices."""
611
def __init__(self, param: inspect.Parameter, literals: List[Any], errors: List[CommandError]): ...
612
613
# Check failures
614
class CheckFailure(CommandError):
615
"""Command check failed."""
616
pass
617
618
class CheckAnyFailure(CheckFailure):
619
"""All checks in check_any failed."""
620
def __init__(self, checks: List[Callable], errors: List[CommandError]): ...
621
checks: List[Callable]
622
errors: List[CommandError]
623
624
class PrivateMessageOnly(CheckFailure):
625
"""Command can only be used in private messages."""
626
pass
627
628
class NoPrivateMessage(CheckFailure):
629
"""Command cannot be used in private messages."""
630
pass
631
632
class NotOwner(CheckFailure):
633
"""User is not the bot owner."""
634
pass
635
636
class MissingRole(CheckFailure):
637
"""User is missing required role."""
638
def __init__(self, missing_role: Union[str, int]): ...
639
missing_role: Union[str, int]
640
641
class BotMissingRole(CheckFailure):
642
"""Bot is missing required role."""
643
def __init__(self, missing_role: Union[str, int]): ...
644
missing_role: Union[str, int]
645
646
class MissingAnyRole(CheckFailure):
647
"""User is missing any of the required roles."""
648
def __init__(self, missing_roles: List[Union[str, int]]): ...
649
missing_roles: List[Union[str, int]]
650
651
class BotMissingAnyRole(CheckFailure):
652
"""Bot is missing any of the required roles."""
653
def __init__(self, missing_roles: List[Union[str, int]]): ...
654
missing_roles: List[Union[str, int]]
655
656
class MissingPermissions(CheckFailure):
657
"""User is missing required permissions."""
658
def __init__(self, missing_permissions: List[str]): ...
659
missing_permissions: List[str]
660
661
class BotMissingPermissions(CheckFailure):
662
"""Bot is missing required permissions."""
663
def __init__(self, missing_permissions: List[str]): ...
664
missing_permissions: List[str]
665
666
class NSFWChannelRequired(CheckFailure):
667
"""Command requires NSFW channel."""
668
def __init__(self, channel: GuildChannel): ...
669
channel: GuildChannel
670
671
# Cooldown errors
672
class CommandOnCooldown(CommandError):
673
"""Command is on cooldown."""
674
def __init__(self, cooldown: Cooldown, retry_after: float, type: BucketType): ...
675
cooldown: Cooldown
676
retry_after: float
677
type: BucketType
678
679
class MaxConcurrencyReached(CommandError):
680
"""Maximum concurrent executions reached."""
681
def __init__(self, number: int, per: BucketType): ...
682
number: int
683
per: BucketType
684
685
# Conversion errors
686
class MemberNotFound(BadArgument):
687
"""Member could not be found."""
688
def __init__(self, argument: str): ...
689
argument: str
690
691
class UserNotFound(BadArgument):
692
"""User could not be found."""
693
def __init__(self, argument: str): ...
694
argument: str
695
696
class MessageNotFound(BadArgument):
697
"""Message could not be found."""
698
def __init__(self, argument: str): ...
699
argument: str
700
701
class ChannelNotFound(BadArgument):
702
"""Channel could not be found."""
703
def __init__(self, argument: str): ...
704
argument: str
705
706
class ChannelNotReadable(BadArgument):
707
"""Channel is not readable by the bot."""
708
def __init__(self, argument: Union[GuildChannel, str]): ...
709
argument: Union[GuildChannel, str]
710
711
class RoleNotFound(BadArgument):
712
"""Role could not be found."""
713
def __init__(self, argument: str): ...
714
argument: str
715
716
class EmojiNotFound(BadArgument):
717
"""Emoji could not be found."""
718
def __init__(self, argument: str): ...
719
argument: str
720
721
class GuildNotFound(BadArgument):
722
"""Guild could not be found."""
723
def __init__(self, argument: str): ...
724
argument: str
725
726
class BadInviteArgument(BadArgument):
727
"""Invalid invite argument."""
728
pass
729
730
class BadColourArgument(BadArgument):
731
"""Invalid colour argument."""
732
def __init__(self, argument: str): ...
733
argument: str
734
735
BadColorArgument = BadColourArgument # Alias
736
```
737
738
### Help System
739
740
Customizable help command system with built-in implementations and support for custom help formats.
741
742
```python { .api }
743
class HelpCommand:
744
"""
745
Base help command implementation.
746
"""
747
def __init__(self, **options): ...
748
749
context: Optional[Context] # Current command context
750
verify_checks: bool # Whether to verify command checks
751
command_attrs: Dict[str, Any] # Attributes for help command
752
753
def copy(self) -> HelpCommand:
754
"""Create a copy of the help command."""
755
756
async def prepare_help_command(self, ctx: Context, command: Optional[Command] = None) -> None:
757
"""Prepare help command for execution."""
758
759
async def command_callback(self, ctx: Context, *, command: str = None) -> None:
760
"""Help command callback."""
761
762
def get_bot_mapping(self) -> Dict[Optional[Cog], List[Command]]:
763
"""Get mapping of cogs to commands."""
764
765
def filter_commands(self, commands: List[Command], *, sort: bool = False, key: Callable = None) -> List[Command]:
766
"""Filter commands based on checks."""
767
768
def get_max_size(self, commands: List[Command]) -> int:
769
"""Get maximum command name size."""
770
771
def get_command_signature(self, command: Command) -> str:
772
"""Get command signature string."""
773
774
def get_opening_note(self) -> str:
775
"""Get opening note for help."""
776
777
def get_ending_note(self) -> str:
778
"""Get ending note for help."""
779
780
def add_indented_commands(self, commands: List[Command], *, heading: str, max_size: int = None) -> None:
781
"""Add indented command list."""
782
783
# Subclass hooks
784
async def send_bot_help(self, mapping: Dict[Optional[Cog], List[Command]]) -> None:
785
"""Send bot help (all commands)."""
786
787
async def send_cog_help(self, cog: Cog) -> None:
788
"""Send help for a specific cog."""
789
790
async def send_group_help(self, group: Group) -> None:
791
"""Send help for a command group."""
792
793
async def send_command_help(self, command: Command) -> None:
794
"""Send help for a specific command."""
795
796
async def send_error_message(self, error: str) -> None:
797
"""Send error message."""
798
799
async def on_help_command_error(self, ctx: Context, error: CommandError) -> None:
800
"""Handle help command errors."""
801
802
def command_not_found(self, string: str) -> str:
803
"""Return message for command not found."""
804
805
def subcommand_not_found(self, command: Command, string: str) -> str:
806
"""Return message for subcommand not found."""
807
808
class DefaultHelpCommand(HelpCommand):
809
"""
810
Default help command implementation with embed formatting.
811
"""
812
def __init__(self, **options): ...
813
814
# Formatting options
815
no_category: str # Name for uncategorized commands
816
paginator: Paginator # Text paginator
817
sort_commands: bool # Whether to sort commands
818
dm_help: Optional[bool] # Whether to DM help
819
dm_help_threshold: Optional[int] # Member count threshold for DM
820
821
class MinimalHelpCommand(HelpCommand):
822
"""
823
Minimal help command implementation.
824
"""
825
def __init__(self, **options): ...
826
827
# Simplified help output
828
sort_commands: bool
829
commands_heading: str
830
aliases_heading: str
831
dm_help: Optional[bool]
832
dm_help_threshold: Optional[int]
833
no_category: str
834
835
class Paginator:
836
"""
837
Text paginator for breaking long help output into pages.
838
"""
839
def __init__(self, prefix: str = '```', suffix: str = '```', max_size: int = 2000, linesep: str = '\n'): ...
840
841
prefix: str # Page prefix
842
suffix: str # Page suffix
843
max_size: int # Maximum page size
844
linesep: str # Line separator
845
846
def add_line(self, line: str = '', *, empty: bool = False) -> None:
847
"""Add a line to the paginator."""
848
849
def close_page(self) -> None:
850
"""Close current page."""
851
852
@property
853
def pages(self) -> List[str]:
854
"""Get all pages."""
855
```
856
857
## Usage Examples
858
859
### Basic Command Bot
860
861
```python
862
import discord
863
from discord.ext import commands
864
865
bot = commands.Bot(command_prefix='!', intents=discord.Intents.default())
866
867
@bot.event
868
async def on_ready():
869
print(f'Bot is ready! Logged in as {bot.user}')
870
871
@bot.command()
872
async def ping(ctx):
873
await ctx.send('Pong!')
874
875
@bot.command()
876
async def echo(ctx, *, message):
877
await ctx.send(message)
878
879
bot.run('YOUR_TOKEN')
880
```
881
882
### Command with Checks and Cooldowns
883
884
```python
885
@bot.command()
886
@commands.has_permissions(manage_messages=True)
887
@commands.cooldown(1, 30, commands.BucketType.guild)
888
async def purge(ctx, amount: int):
889
if amount > 100:
890
await ctx.send("Cannot delete more than 100 messages at once.")
891
return
892
893
deleted = await ctx.channel.purge(limit=amount + 1) # +1 for command message
894
await ctx.send(f"Deleted {len(deleted) - 1} messages.", delete_after=5)
895
```
896
897
### Using Cogs
898
899
```python
900
class ModerationCog(commands.Cog, name="Moderation"):
901
def __init__(self, bot):
902
self.bot = bot
903
904
@commands.command()
905
@commands.has_permissions(kick_members=True)
906
async def kick(self, ctx, member: discord.Member, *, reason=None):
907
await member.kick(reason=reason)
908
await ctx.send(f'{member} has been kicked.')
909
910
@commands.command()
911
@commands.has_permissions(ban_members=True)
912
async def ban(self, ctx, member: discord.Member, *, reason=None):
913
await member.ban(reason=reason)
914
await ctx.send(f'{member} has been banned.')
915
916
async def setup(bot):
917
await bot.add_cog(ModerationCog(bot))
918
```