or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-commands.mdcommands-framework.mdcore-objects.mdevent-handling.mdindex.mduser-interface.mdutilities.mdvoice-audio.mdwebhooks.md

app-commands.mddocs/

0

# Application Commands

1

2

Discord's native slash commands and context menus with built-in parameter validation, autocomplete, localization, and seamless UI integration. Application commands appear in Discord's interface and provide a modern alternative to prefix-based commands.

3

4

## Capabilities

5

6

### Command Tree Management

7

8

The CommandTree manages registration and syncing of application commands with Discord's API.

9

10

```python { .api }

11

class CommandTree:

12

"""

13

Manages application commands for a client.

14

"""

15

def __init__(self, client: Client): ...

16

17

client: Client # Associated Discord client

18

19

async def sync(self, *, guild: Optional[Guild] = None) -> List[AppCommand]:

20

"""

21

Sync commands with Discord.

22

23

Parameters:

24

- guild: Guild to sync to (None for global commands)

25

26

Returns:

27

List of synced AppCommand objects

28

"""

29

30

async def fetch_command(self, command_id: int, *, guild: Optional[Guild] = None) -> AppCommand:

31

"""Fetch a command by ID."""

32

33

async def fetch_commands(self, *, guild: Optional[Guild] = None) -> List[AppCommand]:

34

"""Fetch all commands."""

35

36

def command(

37

self,

38

*,

39

name: str = None,

40

description: str = None,

41

nsfw: bool = False,

42

guild: Optional[Guild] = None,

43

guilds: Optional[List[Guild]] = None,

44

auto_locale_strings: bool = True

45

) -> Callable:

46

"""Decorator to register a slash command."""

47

48

def context_menu(

49

self,

50

*,

51

name: str = None,

52

nsfw: bool = False,

53

guild: Optional[Guild] = None,

54

guilds: Optional[List[Guild]] = None,

55

auto_locale_strings: bool = True

56

) -> Callable:

57

"""Decorator to register a context menu command."""

58

59

def add_command(self, command: Union[Command, ContextMenu], *, guild: Optional[Guild] = None, guilds: Optional[List[Guild]] = None, override: bool = False) -> None:

60

"""Add a command to the tree."""

61

62

def remove_command(self, command: Union[str, Command, ContextMenu], *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> Optional[Union[Command, ContextMenu]]:

63

"""Remove a command from the tree."""

64

65

def get_command(self, name: str, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> Optional[Union[Command, ContextMenu]]:

66

"""Get a command by name."""

67

68

def get_commands(self, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> List[Union[Command, ContextMenu]]:

69

"""Get all commands."""

70

71

def walk_commands(self, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> Iterator[Union[Command, ContextMenu]]:

72

"""Walk all commands."""

73

74

def clear_commands(self, *, guild: Optional[Guild] = None, type: Optional[AppCommandType] = None) -> None:

75

"""Clear all commands."""

76

77

def copy_global_to(self, guild: Guild) -> None:

78

"""Copy global commands to a guild."""

79

80

async def set_translator(self, translator: Translator) -> None:

81

"""Set command translator for localization."""

82

83

def error(self, coro: Callable) -> Callable:

84

"""Decorator for global error handler."""

85

86

def interaction_check(self, coro: Callable) -> Callable:

87

"""Decorator for global interaction check."""

88

```

89

90

### Slash Commands

91

92

Slash commands provide native Discord UI integration with parameter validation and autocomplete.

93

94

```python { .api }

95

class Command:

96

"""

97

Represents a slash command.

98

"""

99

def __init__(

100

self,

101

*,

102

name: str,

103

description: str,

104

callback: Callable,

105

nsfw: bool = False,

106

parent: Optional[Group] = None,

107

guild_ids: Optional[List[int]] = None,

108

auto_locale_strings: bool = True,

109

extras: Dict[Any, Any] = None

110

): ...

111

112

name: str # Command name

113

description: str # Command description

114

callback: Callable # Command function

115

nsfw: bool # Whether command is NSFW

116

parent: Optional[Group] # Parent group

117

guild_ids: Optional[List[int]] # Restricted guild IDs

118

qualified_name: str # Full command name including parent

119

mention: str # Command mention string

120

parameters: List[Parameter] # Command parameters

121

checks: List[Callable] # Command checks

122

extras: Dict[Any, Any] # Extra metadata

123

124

async def __call__(self, interaction: Interaction, **parameters) -> Any:

125

"""Invoke the command."""

126

127

def error(self, coro: Callable) -> Callable:

128

"""Decorator for command error handler."""

129

130

def autocomplete(self, name: str) -> Callable:

131

"""Decorator for parameter autocomplete."""

132

133

def describe(self, **parameters: str) -> Command:

134

"""Add parameter descriptions."""

135

136

def rename(self, **parameters: str) -> Command:

137

"""Rename parameters."""

138

139

class Group(Command):

140

"""

141

Slash command group containing subcommands.

142

"""

143

def __init__(self, *, name: str, description: str, **kwargs): ...

144

145

commands: Dict[str, Union[Command, Group]] # Child commands

146

147

def command(

148

self,

149

*,

150

name: str = None,

151

description: str = None,

152

nsfw: bool = False,

153

auto_locale_strings: bool = True,

154

extras: Dict[Any, Any] = None

155

) -> Callable:

156

"""Decorator to add a subcommand."""

157

158

def group(

159

self,

160

*,

161

name: str = None,

162

description: str = None,

163

nsfw: bool = False,

164

auto_locale_strings: bool = True,

165

extras: Dict[Any, Any] = None

166

) -> Callable:

167

"""Decorator to add a subcommand group."""

168

169

def add_command(self, command: Command) -> None:

170

"""Add a subcommand."""

171

172

def remove_command(self, name: str) -> Optional[Command]:

173

"""Remove a subcommand."""

174

175

def get_command(self, name: str) -> Optional[Command]:

176

"""Get a subcommand by name."""

177

178

# Command decorators

179

def command(

180

*,

181

name: str = None,

182

description: str = None,

183

nsfw: bool = False,

184

guild: Optional[Guild] = None,

185

guilds: Optional[List[Guild]] = None,

186

auto_locale_strings: bool = True,

187

extras: Dict[Any, Any] = None

188

) -> Callable:

189

"""Decorator to create a slash command."""

190

191

def context_menu(

192

*,

193

name: str = None,

194

nsfw: bool = False,

195

guild: Optional[Guild] = None,

196

guilds: Optional[List[Guild]] = None,

197

auto_locale_strings: bool = True,

198

extras: Dict[Any, Any] = None

199

) -> Callable:

200

"""Decorator to create a context menu command."""

201

202

def describe(**parameters: str) -> Callable:

203

"""Decorator to add parameter descriptions."""

204

205

def rename(**parameters: str) -> Callable:

206

"""Decorator to rename parameters."""

207

208

def choices(**parameters: List[Choice]) -> Callable:

209

"""Decorator to add parameter choices."""

210

211

def autocomplete(**parameters: Callable) -> Callable:

212

"""Decorator to add parameter autocomplete."""

213

214

def guild_only() -> Callable:

215

"""Decorator to restrict command to guilds only."""

216

217

def guilds(*guild_ids: int) -> Callable:

218

"""Decorator to restrict command to specific guilds."""

219

220

def default_permissions(**permissions: bool) -> Callable:

221

"""Decorator to set default permissions."""

222

```

223

224

### Context Menu Commands

225

226

Context menu commands appear in right-click menus for users and messages.

227

228

```python { .api }

229

class ContextMenu:

230

"""

231

Represents a context menu command.

232

"""

233

def __init__(

234

self,

235

*,

236

name: str,

237

callback: Callable,

238

nsfw: bool = False,

239

guild_ids: Optional[List[int]] = None,

240

auto_locale_strings: bool = True,

241

extras: Dict[Any, Any] = None

242

): ...

243

244

name: str # Command name

245

type: AppCommandType # Command type (USER or MESSAGE)

246

callback: Callable # Command function

247

nsfw: bool # Whether command is NSFW

248

guild_ids: Optional[List[int]] # Restricted guild IDs

249

qualified_name: str # Command name

250

mention: str # Command mention string

251

checks: List[Callable] # Command checks

252

extras: Dict[Any, Any] # Extra metadata

253

254

async def __call__(self, interaction: Interaction, target: Union[User, Member, Message]) -> Any:

255

"""Invoke the context menu command."""

256

257

def error(self, coro: Callable) -> Callable:

258

"""Decorator for command error handler."""

259

```

260

261

### Parameters & Validation

262

263

Command parameters with type validation, choices, and autocomplete support.

264

265

```python { .api }

266

class Parameter:

267

"""

268

Represents a command parameter.

269

"""

270

def __init__(

271

self,

272

*,

273

name: str,

274

description: str,

275

type: AppCommandOptionType,

276

required: bool = True,

277

default: Any = None,

278

choices: Optional[List[Choice]] = None,

279

autocomplete: Optional[Callable] = None,

280

channel_types: Optional[List[ChannelType]] = None,

281

min_value: Optional[Union[int, float]] = None,

282

max_value: Optional[Union[int, float]] = None,

283

min_length: Optional[int] = None,

284

max_length: Optional[int] = None

285

): ...

286

287

name: str # Parameter name

288

display_name: str # Display name (localized)

289

description: str # Parameter description

290

type: AppCommandOptionType # Parameter type

291

required: bool # Whether parameter is required

292

default: Any # Default value

293

choices: Optional[List[Choice]] # Fixed choices

294

autocomplete: Optional[Callable] # Autocomplete function

295

channel_types: Optional[List[ChannelType]] # Allowed channel types

296

min_value: Optional[Union[int, float]] # Minimum numeric value

297

max_value: Optional[Union[int, float]] # Maximum numeric value

298

min_length: Optional[int] # Minimum string length

299

max_length: Optional[int] # Maximum string length

300

301

class Choice:

302

"""

303

Represents a parameter choice.

304

"""

305

def __init__(self, *, name: str, value: Union[str, int, float]): ...

306

307

name: str # Choice display name

308

value: Union[str, int, float] # Choice value

309

310

class Range:

311

"""

312

Type annotation for numeric parameter ranges.

313

314

Usage: value: app_commands.Range[int, 1, 100]

315

"""

316

def __init__(self, annotation: Type, min: Any = None, max: Any = None): ...

317

318

# Parameter transformers

319

class Transform:

320

"""

321

Transform parameter values with custom logic.

322

323

Usage: value: app_commands.Transform[CustomType, CustomTransformer]

324

"""

325

def __init__(self, annotation: Type, transformer: Type[Transformer]): ...

326

327

class Transformer:

328

"""

329

Base class for parameter transformers.

330

"""

331

async def transform(self, interaction: Interaction, value: Any) -> Any:

332

"""Transform parameter value."""

333

raise NotImplementedError

334

335

async def autocomplete(self, interaction: Interaction, value: Union[int, float, str]) -> List[Choice]:

336

"""Provide autocomplete choices."""

337

return []

338

```

339

340

### Interaction Handling

341

342

Interaction objects represent slash command invocations with response management.

343

344

```python { .api }

345

class Interaction:

346

"""

347

Represents a Discord interaction (slash command, button click, etc.).

348

"""

349

id: int # Interaction ID

350

application_id: int # Application ID

351

type: InteractionType # Interaction type

352

data: Optional[InteractionData] # Interaction data

353

guild_id: Optional[int] # Guild ID

354

guild: Optional[Guild] # Guild object

355

channel_id: Optional[int] # Channel ID

356

channel: Optional[Union[GuildChannel, PartialMessageable]] # Channel object

357

user: User # User who triggered interaction

358

member: Optional[Member] # Member object if in guild

359

token: str # Interaction token

360

version: int # Interaction version

361

message: Optional[Message] # Message for component interactions

362

followup: Followup # Followup webhook

363

response: InteractionResponse # Response manager

364

command: Optional[Union[Command, ContextMenu]] # Command object

365

namespace: Optional[Namespace] # Parameter namespace

366

locale: str # User locale

367

guild_locale: Optional[str] # Guild locale

368

created_at: datetime # Interaction creation time

369

expires_at: datetime # When interaction expires

370

371

@property

372

def client(self) -> Client:

373

"""Client that received the interaction."""

374

375

def is_expired(self) -> bool:

376

"""Check if interaction has expired."""

377

378

async def original_response(self) -> InteractionMessage:

379

"""Get the original response message."""

380

381

async def edit_original_response(self, **kwargs) -> InteractionMessage:

382

"""Edit the original response."""

383

384

async def delete_original_response(self) -> None:

385

"""Delete the original response."""

386

387

async def translate(self, string: locale_str, locale: str = None, **kwargs) -> str:

388

"""Translate a localizable string."""

389

390

class InteractionResponse:

391

"""

392

Manages interaction responses.

393

"""

394

def __init__(self, parent: Interaction): ...

395

396

is_done(self) -> bool:

397

"""Check if response has been sent."""

398

399

async def send_message(

400

self,

401

content: str = None,

402

*,

403

embed: Embed = None,

404

embeds: List[Embed] = None,

405

file: File = None,

406

files: List[File] = None,

407

view: View = None,

408

ephemeral: bool = False,

409

tts: bool = False,

410

allowed_mentions: AllowedMentions = None,

411

suppress_embeds: bool = False

412

) -> None:

413

"""Send response message."""

414

415

async def defer(self, *, ephemeral: bool = False, thinking: bool = False) -> None:

416

"""Defer response to send later."""

417

418

async def pong(self) -> None:

419

"""Respond to ping interaction."""

420

421

async def edit_message(

422

self,

423

*,

424

content: str = None,

425

embed: Embed = None,

426

embeds: List[Embed] = None,

427

attachments: List[Attachment] = None,

428

view: View = None,

429

allowed_mentions: AllowedMentions = None,

430

suppress_embeds: bool = False

431

) -> None:

432

"""Edit original message."""

433

434

async def autocomplete(self, *, choices: List[Choice]) -> None:

435

"""Respond with autocomplete choices."""

436

437

class Namespace:

438

"""

439

Container for command parameters.

440

"""

441

def __init__(self, interaction: Interaction, data: InteractionData): ...

442

443

def __getattr__(self, name: str) -> Any:

444

"""Get parameter value by name."""

445

446

def __getitem__(self, name: str) -> Any:

447

"""Get parameter value by name."""

448

449

def __contains__(self, name: str) -> bool:

450

"""Check if parameter exists."""

451

452

def __iter__(self) -> Iterator[str]:

453

"""Iterate parameter names."""

454

455

def get(self, name: str, default: Any = None) -> Any:

456

"""Get parameter value with default."""

457

```

458

459

### Command Checks & Permissions

460

461

Permission validation and custom checks for application commands.

462

463

```python { .api }

464

# Check decorators

465

def check(predicate: Callable[[Interaction], Awaitable[bool]]) -> Callable:

466

"""Add a check to a command."""

467

468

# Permission checks

469

def has_role(role: Union[int, str]) -> Callable:

470

"""Check if user has a specific role."""

471

472

def has_any_role(*roles: Union[int, str]) -> Callable:

473

"""Check if user has any of the specified roles."""

474

475

def has_permissions(**permissions: bool) -> Callable:

476

"""Check if user has specific permissions."""

477

478

def bot_has_permissions(**permissions: bool) -> Callable:

479

"""Check if bot has specific permissions."""

480

481

def default_permissions(**permissions: bool) -> Callable:

482

"""Set default permissions for the command."""

483

484

# Cooldown system

485

class Cooldown:

486

"""

487

Application command cooldown.

488

"""

489

def __init__(self, rate: int, per: float): ...

490

491

rate: int # Number of uses allowed

492

per: float # Time period in seconds

493

494

def cooldown(rate: int, per: float) -> Callable:

495

"""Add cooldown to a command."""

496

497

def dynamic_cooldown(cooldown_func: Callable[[Interaction], Optional[Cooldown]]) -> Callable:

498

"""Add dynamic cooldown to a command."""

499

```

500

501

### Error Handling

502

503

Comprehensive error handling for application commands with specific exception types.

504

505

```python { .api }

506

# Base application command errors

507

class AppCommandError(DiscordException):

508

"""Base exception for application command errors."""

509

pass

510

511

class CommandInvokeError(AppCommandError):

512

"""Exception occurred during command execution."""

513

def __init__(self, command: Union[Command, ContextMenu], e: Exception): ...

514

command: Union[Command, ContextMenu]

515

original: Exception

516

517

# Parameter errors

518

class TransformerError(AppCommandError):

519

"""Parameter transformer failed."""

520

def __init__(self, value: Any, type: AppCommandOptionType, transformer: Type[Transformer]): ...

521

value: Any

522

type: AppCommandOptionType

523

transformer: Type[Transformer]

524

525

# Command management errors

526

class CommandAlreadyRegistered(AppCommandError):

527

"""Command is already registered."""

528

def __init__(self, name: str, guild_id: Optional[int]): ...

529

name: str

530

guild_id: Optional[int]

531

532

class CommandSignatureMismatch(AppCommandError):

533

"""Command signature doesn't match Discord's requirements."""

534

pass

535

536

class CommandNotFound(AppCommandError):

537

"""Command was not found."""

538

def __init__(self, name: str, parents: List[str]): ...

539

name: str

540

parents: List[str]

541

542

class CommandLimitReached(AppCommandError):

543

"""Maximum number of commands reached."""

544

def __init__(self, guild_id: Optional[int], limit: int, type: AppCommandType): ...

545

guild_id: Optional[int]

546

limit: int

547

type: AppCommandType

548

549

# Check failures

550

class CheckFailure(AppCommandError):

551

"""Command check failed."""

552

pass

553

554

class NoPrivateMessage(CheckFailure):

555

"""Command cannot be used in private messages."""

556

pass

557

558

class MissingRole(CheckFailure):

559

"""User is missing required role."""

560

def __init__(self, missing_role: Union[str, int]): ...

561

missing_role: Union[str, int]

562

563

class MissingAnyRole(CheckFailure):

564

"""User is missing any of the required roles."""

565

def __init__(self, missing_roles: List[Union[str, int]]): ...

566

missing_roles: List[Union[str, int]]

567

568

class MissingPermissions(CheckFailure):

569

"""User is missing required permissions."""

570

def __init__(self, missing_permissions: List[str]): ...

571

missing_permissions: List[str]

572

573

class BotMissingPermissions(CheckFailure):

574

"""Bot is missing required permissions."""

575

def __init__(self, missing_permissions: List[str]): ...

576

missing_permissions: List[str]

577

578

class CommandOnCooldown(CheckFailure):

579

"""Command is on cooldown."""

580

def __init__(self, cooldown: Cooldown, retry_after: float): ...

581

cooldown: Cooldown

582

retry_after: float

583

584

# Sync errors

585

class CommandSyncFailure(AppCommandError):

586

"""Failed to sync commands with Discord."""

587

pass

588

589

class MissingApplicationID(CommandSyncFailure):

590

"""Application ID is missing."""

591

pass

592

593

# Translation errors

594

class TranslationError(AppCommandError):

595

"""Translation failed."""

596

def __init__(self, message: str, key: locale_str, locale: str): ...

597

message: str

598

key: locale_str

599

locale: str

600

```

601

602

### Localization Support

603

604

Built-in localization system for command names, descriptions, and responses.

605

606

```python { .api }

607

class locale_str:

608

"""

609

Represents a localizable string.

610

"""

611

def __init__(self, message: str, **kwargs): ...

612

613

message: str # Base message string

614

extras: Dict[str, Any] # Extra data for formatting

615

616

class Translator:

617

"""

618

Base class for command translators.

619

"""

620

async def translate(self, string: locale_str, locale: str, context: TranslationContext) -> Optional[str]:

621

"""Translate a localizable string."""

622

raise NotImplementedError

623

624

class TranslationContext:

625

"""

626

Context for translation requests.

627

"""

628

location: TranslationContextLocation # Where translation is used

629

data: Any # Context-specific data

630

631

class TranslationContextLocation(Enum):

632

"""Location where translation is being performed."""

633

command_name = 1

634

command_description = 2

635

parameter_name = 3

636

parameter_description = 4

637

choice_name = 5

638

other = 6

639

640

TranslationContextTypes = Union[

641

Command,

642

ContextMenu,

643

Parameter,

644

Choice,

645

Group

646

]

647

```

648

649

## Usage Examples

650

651

### Basic Slash Command

652

653

```python

654

import discord

655

from discord.ext import commands

656

657

class MyBot(commands.Bot):

658

def __init__(self):

659

intents = discord.Intents.default()

660

super().__init__(command_prefix='!', intents=intents)

661

662

async def setup_hook(self):

663

# Sync commands on startup

664

await self.tree.sync()

665

print(f"Synced {len(self.tree.get_commands())} commands")

666

667

bot = MyBot()

668

669

@bot.tree.command(name="hello", description="Say hello to someone")

670

@app_commands.describe(user="The user to greet")

671

async def hello(interaction: discord.Interaction, user: discord.Member):

672

await interaction.response.send_message(f"Hello {user.mention}!")

673

674

bot.run('YOUR_TOKEN')

675

```

676

677

### Slash Command with Choices and Validation

678

679

```python

680

@bot.tree.command(name="roll", description="Roll dice")

681

@app_commands.describe(

682

sides="Number of sides on the die",

683

count="Number of dice to roll"

684

)

685

@app_commands.choices(sides=[

686

app_commands.Choice(name="4-sided (d4)", value=4),

687

app_commands.Choice(name="6-sided (d6)", value=6),

688

app_commands.Choice(name="8-sided (d8)", value=8),

689

app_commands.Choice(name="10-sided (d10)", value=10),

690

app_commands.Choice(name="12-sided (d12)", value=12),

691

app_commands.Choice(name="20-sided (d20)", value=20),

692

])

693

async def roll_dice(

694

interaction: discord.Interaction,

695

sides: app_commands.Choice[int],

696

count: app_commands.Range[int, 1, 10] = 1

697

):

698

import random

699

700

rolls = [random.randint(1, sides.value) for _ in range(count)]

701

total = sum(rolls)

702

703

embed = discord.Embed(title="🎲 Dice Roll Results", color=0x00ff00)

704

embed.add_field(name="Rolls", value=" + ".join(map(str, rolls)), inline=False)

705

embed.add_field(name="Total", value=str(total), inline=True)

706

embed.add_field(name="Dice", value=f"{count}d{sides.value}", inline=True)

707

708

await interaction.response.send_message(embed=embed)

709

```

710

711

### Context Menu Command

712

713

```python

714

@bot.tree.context_menu(name="Get User Info")

715

async def user_info(interaction: discord.Interaction, user: discord.Member):

716

embed = discord.Embed(title=f"Info for {user.display_name}", color=user.color)

717

embed.set_thumbnail(url=user.display_avatar.url)

718

embed.add_field(name="ID", value=user.id, inline=True)

719

embed.add_field(name="Joined", value=f"<t:{int(user.joined_at.timestamp())}:R>", inline=True)

720

embed.add_field(name="Roles", value=len(user.roles) - 1, inline=True)

721

722

await interaction.response.send_message(embed=embed, ephemeral=True)

723

```

724

725

### Command Group with Subcommands

726

727

```python

728

@bot.tree.command(name="config", description="Bot configuration commands")

729

async def config_group(interaction: discord.Interaction):

730

# This won't be called as it has subcommands

731

pass

732

733

@config_group.subcommand(name="prefix", description="Set bot prefix")

734

@app_commands.describe(new_prefix="New command prefix")

735

async def config_prefix(interaction: discord.Interaction, new_prefix: str):

736

# Update prefix logic here

737

await interaction.response.send_message(f"Prefix set to `{new_prefix}`")

738

739

@config_group.subcommand(name="channel", description="Set bot channel")

740

@app_commands.describe(channel="Channel for bot commands")

741

async def config_channel(interaction: discord.Interaction, channel: discord.TextChannel):

742

# Update channel logic here

743

await interaction.response.send_message(f"Bot channel set to {channel.mention}")

744

```

745

746

### Autocomplete Example

747

748

```python

749

# Simple autocomplete

750

@bot.tree.command(name="timezone", description="Set your timezone")

751

async def timezone_command(interaction: discord.Interaction, timezone: str):

752

# Timezone setting logic here

753

await interaction.response.send_message(f"Timezone set to {timezone}")

754

755

@timezone_command.autocomplete('timezone')

756

async def timezone_autocomplete(interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:

757

timezones = ["UTC", "US/Eastern", "US/Central", "US/Mountain", "US/Pacific", "Europe/London", "Europe/Berlin"]

758

return [

759

app_commands.Choice(name=tz, value=tz)

760

for tz in timezones if current.lower() in tz.lower()

761

][:25] # Discord limits to 25 choices

762

```