mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-18 15:06:07 +00:00
parent
6886f1d01a
commit
c92422d185
163
examples/app_commands/transformers.py
Normal file
163
examples/app_commands/transformers.py
Normal file
@ -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…
x
Reference in New Issue
Block a user