1 changed files with 163 additions and 0 deletions
@ -0,0 +1,163 @@ |
|||
# This example builds on the concepts of the app_commands/basic.py example |
|||
# It's suggested to look at that one to understand certain concepts first. |
|||
|
|||
from typing import Literal, Union, NamedTuple |
|||
from enum import Enum |
|||
|
|||
import discord |
|||
from discord import app_commands |
|||
|
|||
|
|||
MY_GUILD = discord.Object(id=0) # replace with your guild id |
|||
|
|||
|
|||
class MyClient(discord.Client): |
|||
def __init__(self): |
|||
super().__init__(intents=discord.Intents.default()) |
|||
self.tree = app_commands.CommandTree(self) |
|||
|
|||
async def setup_hook(self): |
|||
self.tree.copy_global_to(guild=MY_GUILD) |
|||
await self.tree.sync(guild=MY_GUILD) |
|||
|
|||
|
|||
client = MyClient() |
|||
|
|||
|
|||
@client.event |
|||
async def on_ready(): |
|||
print(f'Logged in as {client.user} (ID: {client.user.id})') |
|||
print('------') |
|||
|
|||
|
|||
# A transformer is a class that specifies how a parameter in your code |
|||
# should behave both when used on Discord and when you receive it from Discord. |
|||
# There are a few built-in transformers, this example will show these along with |
|||
# creating your own for maximum flexibility. |
|||
|
|||
# The first built-in transformer is app_commands.Range |
|||
# It works on `str`, `int`, and `float` options and tells you |
|||
# the maximum and minimum values (or length in the case of `str`) allowed |
|||
|
|||
|
|||
@client.tree.command() |
|||
@app_commands.describe(first='The first number to add', second='The second number to add') |
|||
async def add( |
|||
interaction: discord.Interaction, |
|||
# This makes it so the first parameter can only be between 0 to 100. |
|||
first: app_commands.Range[int, 0, 100], |
|||
# This makes it so the second parameter must be over 0, with no maximum limit. |
|||
second: app_commands.Range[int, 0, None], |
|||
): |
|||
"""Adds two numbers together""" |
|||
await interaction.response.send_message(f'{first} + {second} = {first + second}', ephemeral=True) |
|||
|
|||
|
|||
# Other transformers include regular type hints that are supported by Discord |
|||
# Examples of these include int, str, float, bool, User, Member, Role, and any channel type. |
|||
# Since there are a lot of these, for brevity only a channel example will be included. |
|||
|
|||
# This command shows how to only show text and voice channels to a user using the Union type hint |
|||
# combined with the VoiceChannel and TextChannel types. |
|||
@client.tree.command(name='channel-info') |
|||
@app_commands.describe(channel='The channel to get info of') |
|||
async def channel_info(interaction: discord.Interaction, channel: Union[discord.VoiceChannel, discord.TextChannel]): |
|||
"""Shows basic channel info for a text or voice channel.""" |
|||
|
|||
embed = discord.Embed(title='Channel Info') |
|||
embed.add_field(name='Name', value=channel.name, inline=True) |
|||
embed.add_field(name='ID', value=channel.id, inline=True) |
|||
embed.add_field( |
|||
name='Type', |
|||
value='Voice' if isinstance(channel, discord.VoiceChannel) else 'Text', |
|||
inline=True, |
|||
) |
|||
|
|||
embed.set_footer(text='Created').timestamp = channel.created_at |
|||
await interaction.response.send_message(embed=embed) |
|||
|
|||
|
|||
# In order to support choices, the library has a few ways of doing this. |
|||
# The first one is using a typing.Literal for basic choices. |
|||
|
|||
# On Discord, this will show up as two choices, Buy and Sell. |
|||
# In the code, you will receive either 'Buy' or 'Sell' as a string. |
|||
@client.tree.command() |
|||
@app_commands.describe(action='The action to do in the shop', item='The target item') |
|||
async def shop(interaction: discord.Interaction, action: Literal['Buy', 'Sell'], item: str): |
|||
"""Interact with the shop""" |
|||
await interaction.response.send_message(f'Action: {action}\nItem: {item}') |
|||
|
|||
|
|||
# The second way to do choices is via an Enum from the standard library |
|||
# On Discord, this will show up as four choices: apple, banana, cherry, and dragonfruit |
|||
# In the code, you will receive the appropriate enum value. |
|||
|
|||
|
|||
class Fruits(Enum): |
|||
apple = 0 |
|||
banana = 1 |
|||
cherry = 2 |
|||
dragonfruit = 3 |
|||
|
|||
|
|||
@client.tree.command() |
|||
@app_commands.describe(fruit='The fruit to choose') |
|||
async def fruit(interaction: discord.Interaction, fruit: Fruits): |
|||
"""Choose a fruit!""" |
|||
await interaction.response.send_message(repr(fruit)) |
|||
|
|||
|
|||
# You can also make your own transformer by inheriting from app_commands.Transformer |
|||
|
|||
|
|||
class Point(NamedTuple): |
|||
x: int |
|||
y: int |
|||
|
|||
|
|||
# The default transformer takes in a string option and you can transform |
|||
# it into any value you'd like. |
|||
# |
|||
# Transformers also support various other settings such as overriding |
|||
# properties like `choices`, `max_value`, `min_value`, `type`, or `channel_types`. |
|||
# However, this is outside of the scope of this example so check the documentation |
|||
# for more information. |
|||
class PointTransformer(app_commands.Transformer): |
|||
async def transform(self, interaction: discord.Interaction, value: str) -> Point: |
|||
(x, _, y) = value.partition(',') |
|||
return Point(x=int(x.strip()), y=int(y.strip())) |
|||
|
|||
|
|||
@client.tree.command() |
|||
async def graph( |
|||
interaction: discord.Interaction, |
|||
# In order to use the transformer, you should use Transform to tell the |
|||
# library to use it. |
|||
point: app_commands.Transform[Point, PointTransformer], |
|||
): |
|||
await interaction.response.send_message(str(point)) |
|||
|
|||
|
|||
# For more basic transformers for your own types without too much repetition, |
|||
# a concept known as "inline transformers" is supported. This allows you to use |
|||
# a classmethod to have a string based transformer. It's only useful |
|||
# if you only care about transforming a string to a class and nothing else. |
|||
class Point3D(NamedTuple): |
|||
x: int |
|||
y: int |
|||
z: int |
|||
|
|||
# This is the same as the above transformer except inline |
|||
@classmethod |
|||
async def transform(cls, interaction: discord.Interaction, value: str): |
|||
x, y, z = value.split(',') |
|||
return cls(x=int(x.strip()), y=int(y.strip()), z=int(z.strip())) |
|||
|
|||
|
|||
@client.tree.command() |
|||
async def graph3d(interaction: discord.Interaction, point: Point3D): |
|||
await interaction.response.send_message(str(point)) |
|||
|
|||
|
|||
client.run('token') |
Loading…
Reference in new issue