An interaction takes place when your application recieves an application (slash) command or a user interacts with a message component such as a Button.
This documentation will cover common scenarios such as handling an interaction, persisting a button interaction on restart, and using action groups.
When the bot receives an interaction, Discord will expect it to be acknowledged and handled within a timely manner.
Generally, this can simply be done by responding to the interaction using the message()
method:
$this->message('Hello to you!')->reply($interaction, ephemeral: true);
This can alternatively be done using the Interaction
instance directly:
$interaction->respondWithMessage(
$this->message('Hello to you!')->build(),
ephemeral: true
);
When responding to an interaction that will take longer than 3 seconds to respond to, it is recommended to acknowledge the interaction immediately before asynchronously handling your task:
$interaction
->acknowledge()
->then(fn ($interaction) => $this->handleLongTask($interaction));
When using buttons and select menus, Laracord provides a persistent, easy to use interaction router that gives a Laravel-like feel to handling responses.
In the example below, we will pass a route to a few buttons and a select menu and then handle the responses in the router.
use Discord\Parts\Interactions\Interaction;
/**
* Handle the command.
*/
public function handle($message, $args)
{
return $this
->message('Try out some interactions below.')
->title('Interaction Example')
->button('👋 Hello', route: 'wave:hello')
->button('👋 Goodbye', route: 'wave:goodbye')
->select([
'Apples',
'Bananas',
'Oranges',
], route: 'fruit', placeholder: 'Select a fruit...');
->send($message);
}
/**
* The command interaction routes.
*/
public function interactions(): array
{
return [
'wave:{type}' => fn (Interaction $interaction, string $type) =>
$this
->message("You clicked {$type}.")
->reply($interaction, ephemeral: true),
'fruit' => fn (Interaction $interaction) =>
$this
->message("You selected {$interaction->data->values[0]}.")
->reply($interaction, ephemeral: true),
];
}
A neat feature in Discord is the ability to respond to an interaction using a Modal. This allows the user to input and submit text for it to then get parsed by the bot.
Below we will show a modal for creating a ticket consisting of a Title
text input and Description
paragraph.
$this
->modal('Create Ticket')
->text('Title', placeholder: 'Enter a title.', minLength: 2, maxLength: 32, required: true)
->paragraph('Description', placeholder: 'Please describe the issue in detail.', minLength: 5, maxLength: 256, required: true)
->submit(fn ($interaction, $components) => $this->createTicket($interaction, $components))
->show($interaction);
Tip
If you need to show a modal outside of a command, you can use the
HasModal
trait but it will still require an$interaction
.
In the example above, once the modal is submitted, we will be passing the $interaction
instance and modal $components
to our createTicket()
method. From there, we will handle the data and then acknowledge the response.
use App\Models\Ticket;
use Discord\Helpers\Collection;
use Discord\Parts\Interactions\Interaction;
protected function createTicket(Interaction $interaction, Collection $components)
{
$title = $components->get('custom_id', 'title')->value;
$description = $components->get('custom_id', 'description')->value;
$ticket = Ticket::create([
'title' => $title,
'description' => $description,
]);
return $this->message("Your ticket with ID {$ticket->id} has been created.")->reply($interaction, ephemeral: true);
}