Listeners
discord_ui.listeners
A module for listeners that are going to be attached to a message. You could think of it like a cog but for message components.
from discord_ui import Listener
Usage
To use the Listener
class, you need to create a subclass of it
Example
class MyListener(Listener):
...
Listeners
To add a button listener, you need to use the Listener.button
deorator
class MyListener(Listener):
...
@Listener.button("custom_id here")
async def somebutton(self, ctx):
...
This will add a button listener that will wait for a button with the custom id “custom_id here”
To add a select listener, you need to use the Listener.select
decoratorr
class MyListener(Listener):
...
@Listener.select("my_id")
async def someselect(self, ctx):
...
This will add a select menu listener that will wait for a select menu with the custom id “my_id”
You can filter the select callback with the values
parameter
class MyListener(Listener):
...
@Listener.select("my_id", values=["2"])
async def someselect(self, ctx):
...
The callback will now be only called if the selected values of a select menu equal to values
There are some more useful things you can use
Class
You can add a timeout to the listener after which the listener will be removed from the message
class MyListener(Listener):
def __init__(self):
self.timeout = 20 # 20 seconds timeout
If you set timeout to None
, the listener will never timeout
You can also add a list of target users to the listener
class MyListener(Listener):
def __init__(self):
self.target_users = [a, list, of, users]
And last but not least, you can supress the discord_ui.listener.NoListenerFound errors when no listener could be found
class MyListener(Listener):
def __init__(self):
self.supress_no_listener_found = True
Sending
To send components and add the listener, you can use five different ways
First method:
@bot.listen()
async def on_message(message)
class MyListener(Listener):
def __init__(self):
pass
@Listener.button("test")
async def test(self, ctx):
...
await message.channel.send("showcase", components=[Button("this is a showcase", "test")], listener=MyListener())
Second method:
@bot.listen()
async def on_message(message)
class MyListener(Listener):
def __init__(self):
self.components = [Button("this is a showcase", "test")]
@Listener.button("test")
async def test(self, ctx):
...
# MyListener.components will be used for the components in the message
await message.channel.send("showcase", listener=MyListener())
Third method:
@bot.listen()
async def on_message(message)
class MyListener(Listener):
def __init__(self):
...
@Listener.button("test")
async def test(self, ctx):
...
msg = await message.channel.send("showcase", components=[Button("this is a showcase", "test")])
msg.attach_listener(MyListener())
Fourth method:
ui = discord_ui.UI(bot)
@bot.listen()
async def on_message(message)
class MyListener(Listener):
def __init__(self):
pass
@Listener.button("test")
async def test(self, ctx):
...
msg = await message.channel.send("showcase", components=[Button("this is a showcase", "test")])
ui.components.attach_listener_to(msg, MyListener())
And the last method:
ui = discord_ui.UI(bot)
@bot.listen()
async def on_message(message)
class MyListener(Listener):
def __init__(self):
pass
@Listener.button("test")
async def test(self, ctx):
...
msg = await message.channel.send("showcase", components=[Button("this is a showcase", "test")])
MyListener().attach_me_to(msg)
- class discord_ui.listener.Listener(timeout=180.0, target_users=None)
- A class for a listener attached to a message that will receive components of it.
To use this class you have to create a subclass inhering this class
class MyListener(Listener) ...
- timeout:
float
, optional A timeout after how many seconds the listener shouold be deleted. If
None
, the listener will never timeout- target_users: List[
discord.Member
|discord.User
|int
|str
] A list of users or user ids from which the interactions has to be be received. Every interaction by other users will be ignored
- attach_me_to(message)
Attaches this listener to a message after it was sent
- message:
Message
The target message
- message:
- static button(custom_id=None)
A decorator that will setup a callback for a button
- custom_id:
str
, optional - The custom id of the target button. If no custom_id is passed, the name of the callback will be used for the custom id.
Note that you can’t have two callbacks with the same function name
class MyListener(Listener): def __init__(self, ...): ... @Listener.button("my_id") async def callback(self, ctx): ...
- custom_id:
- components: List[Union[List[Button, LinkButton, SelectMenu], Button, LinkButton, SelectMenu]]
The components that are going to be send together with the listener
- static on_error(exception_cls=<class 'BaseException'>)
Decorator for a function that will handle exceptions
- exception_cls:
class
, optional The type of the exception that should be handled; default Exception
from discord.ext.commands import CheckFailure class MyListener(Listener): ... # exception handler for checkfailures @Listener.on_error(CheckFailure) async def check_failure(self, ctx, exception): await ctx.send("check failed: " + str(exception), hidden=True) @Listener.on_error(Exception) async def exception(self, ctx, exception): await ctx.send("base exception occured " + str(exception))
- exception_cls:
- async put_me_to(message)
Attaches this listener to a message and edits it if the message is missing components
- message:
Message
The target message
- message:
- static select(custom_id=None, values=None)
A decorator that will set a callback up for a select menu
- custom_id:
str
, optional - The custom id of the target menu. If no id specified, the name of the callback will be used.
Note that you can’t have two callbacks with the same function name
- values: List[
str
], optional What values must be selected in order to invoke the callback; default None
class MyListener(Listener): def __init__(self, ...) ... @Listener.select("my_id") async def callback(self, ctx): ... # This callback will be only called if the selected values of the menu are '2' @Listener.select("my_id", values=['2']) async def othere_callback(self, ctx): ...
- custom_id:
- supress_no_listener_found: bool
Whether discord_ui.listener.NoListenerFound should be supressed and not get thrown when no target component listener could be found
- property target_users: List[int]
A list of user ids from which the interaction has to come
- timeout: float
Timeout after how many seconds the listener should timeout and be deleted
- static wrong_user()
Decorator for a function that will be called when a user that is not in .target_users tried to use a component
class MyListener(Listener): def __init__(self): self.components = [Button()] self.target_users = [785567635802816595] @Listener.button() async def a_button(self, ctx): await ctx.send("you are allowed") @Listener.wrong_user() async def you_wrong(self, ctx): await ctx.send("this component is not for you")