diff --git a/src/Bot/Concerns/HasApplicationCommands.php b/src/Bot/Concerns/HasApplicationCommands.php index b7e8073..99ed864 100644 --- a/src/Bot/Concerns/HasApplicationCommands.php +++ b/src/Bot/Concerns/HasApplicationCommands.php @@ -2,6 +2,7 @@ namespace Laracord\Bot\Concerns; +use Discord\Discord; use Discord\Parts\Interactions\Command\Option; use Illuminate\Support\Arr; use Laracord\Bot\Hook; @@ -11,6 +12,11 @@ use function React\Async\await; use function React\Promise\all; +/** + * Concern to manage application commands. + * + * @method Discord discord() Get the Discord instance. + */ trait HasApplicationCommands { /** @@ -44,14 +50,14 @@ protected function bootApplicationCommands(): self $existing = []; - $existing[] = $this->discord->application->commands->freshen(); + $existing[] = $this->discord()->application->commands->freshen(); - foreach ($this->discord->guilds as $guild) { + foreach ($this->discord()->guilds as $guild) { $existing[] = $guild->commands->freshen(); } $existing = all($existing)->then(fn ($commands) => collect($commands) - ->flatMap(fn ($command) => $command->toArray()) + ->flatMap(fn ($command) => $command->jsonSerialize()) ->map(fn ($command) => collect($command->getCreatableAttributes()) ->merge([ 'id' => $command->id, @@ -182,7 +188,7 @@ protected function bootApplicationCommands(): self if ($command['state'] instanceof ContextMenu) { $menu = $command['state']; - $this->discord->listenCommand( + $this->discord()->listenCommand( $name, fn ($interaction) => rescue(fn () => $menu->maybeHandle($interaction)) ); @@ -208,7 +214,7 @@ protected function bootApplicationCommands(): self $subcommands = $subcommands->merge($subcommandGroups); if ($subcommands->isNotEmpty()) { - $subcommands->each(fn ($names) => $this->discord->listenCommand( + $subcommands->each(fn ($names) => $this->discord()->listenCommand( $names, fn ($interaction) => rescue(fn () => $command->maybeHandle($interaction)), fn ($interaction) => rescue(fn () => $command->maybeHandleAutocomplete($interaction)) @@ -217,7 +223,7 @@ protected function bootApplicationCommands(): self return; } - $this->discord->listenCommand( + $this->discord()->listenCommand( $name, fn ($interaction) => rescue(fn () => $command->maybeHandle($interaction)), fn ($interaction) => rescue(fn () => $command->maybeHandleAutocomplete($interaction)) @@ -236,21 +242,7 @@ protected function bootApplicationCommands(): self */ protected function registerApplicationCommand(ApplicationCommand $command): void { - if ($command->getGuild()) { - $guild = $this->discord->guilds->get('id', $command->getGuild()); - - if (! $guild) { - $this->logger->warning("The {$command->getName()} command failed to register because the guild {$command->getGuild()} could not be found."); - - return; - } - - $guild->commands->save($command->create()); - - return; - } - - $this->discord->application->commands->save($command->create()); + $command->create()->save(); } /** @@ -259,7 +251,7 @@ protected function registerApplicationCommand(ApplicationCommand $command): void protected function unregisterApplicationCommand(string $id, ?string $guildId = null): void { if ($guildId) { - $guild = $this->discord->guilds->get('id', $guildId); + $guild = $this->discord()->guilds->get('id', $guildId); if (! $guild) { $this->logger->warning("The command with ID {$id} failed to unregister because the guild {$guildId} could not be found."); @@ -272,6 +264,6 @@ protected function unregisterApplicationCommand(string $id, ?string $guildId = n return; } - $this->discord->application->commands->delete($id); + $this->discord()->application->commands->delete($id); } } diff --git a/src/Commands/AbstractCommand.php b/src/Commands/AbstractCommand.php index c510af4..b8834d4 100644 --- a/src/Commands/AbstractCommand.php +++ b/src/Commands/AbstractCommand.php @@ -14,6 +14,13 @@ abstract class AbstractCommand { use HasHandler, HasLaracord, HasModal; + /** + * The command usage. + * + * @var string + */ + protected $usage = ''; + /** * The command name. * @@ -123,7 +130,7 @@ public function message($content = '') public function isAdmin(User|string $user): bool { if (! $user instanceof User) { - $user = $this->discord->users->get('id', $user); + $user = $this->discord()->users->get('id', $user); } if ($this->bot->getAdmins()) { diff --git a/src/Commands/ApplicationCommand.php b/src/Commands/ApplicationCommand.php index d07076d..78214a9 100644 --- a/src/Commands/ApplicationCommand.php +++ b/src/Commands/ApplicationCommand.php @@ -3,6 +3,8 @@ namespace Laracord\Commands; use Closure; +use Discord\Builders\CommandBuilder; +use Discord\Parts\Interactions\Command\Command; use Discord\Parts\Interactions\Interaction; use Discord\Parts\Permissions\RolePermission; @@ -25,6 +27,30 @@ abstract class ApplicationCommand extends AbstractCommand */ protected bool $nsfw = false; + /** + * Create a Discord command instance. + */ + public function create(): Command + { + $command = CommandBuilder::new() + ->setName($this->getName()) + ->setDescription($this->getDescription()) + ->setType($this->getType()) + ->setDmPermission($this->canDirectMessage()) + ->setNsfw($this->isNsfw()); + + if ($permissions = $this->getPermissions()) { + $command = $command->setDefaultMemberPermissions($permissions); + } + + $command = collect($command->jsonSerialize()) + ->put('guild_id', $this->getGuild()) + ->filter() + ->all(); + + return new Command($this->discord(), $command); + } + /** * Retrieve the slash command bitwise permission. */ diff --git a/src/Commands/Command.php b/src/Commands/Command.php index 9305ac4..160b9aa 100644 --- a/src/Commands/Command.php +++ b/src/Commands/Command.php @@ -17,13 +17,6 @@ abstract class Command extends AbstractCommand implements CommandContract */ protected $aliases = []; - /** - * The command usage. - * - * @var string - */ - protected $usage = ''; - /** * Maybe handle the command. */ diff --git a/src/Commands/SlashCommand.php b/src/Commands/SlashCommand.php index 4c90978..aa503cf 100644 --- a/src/Commands/SlashCommand.php +++ b/src/Commands/SlashCommand.php @@ -52,7 +52,7 @@ public function create(): DiscordCommand } } - $command = collect($command->toArray()) + $command = collect($command->jsonSerialize()) ->put('guild_id', $this->getGuild()) ->filter() ->all();