-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from dc-Ragnarok/feat/message-components
- Loading branch information
Showing
33 changed files
with
495 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ discord.log | |
.phpunit.cache | ||
.php-cs-fixer.cache | ||
composer.lock | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Exan\Fenrir\Interaction; | ||
|
||
use Exan\Fenrir\Discord; | ||
use Exan\Fenrir\Interaction\Helpers\InteractionCallbackBuilder; | ||
use Exan\Fenrir\Websocket\Events\InteractionCreate; | ||
use React\Promise\ExtendedPromiseInterface; | ||
|
||
class ButtonInteraction | ||
{ | ||
public function __construct(public readonly InteractionCreate $interaction, private Discord $discord) | ||
{ | ||
} | ||
|
||
public function createInteractionResponse( | ||
InteractionCallbackBuilder $interactionCallbackBuilder | ||
): ExtendedPromiseInterface { | ||
return $this->discord->rest->webhook->createInteractionResponse( | ||
$this->interaction->id, | ||
$this->interaction->token, | ||
$interactionCallbackBuilder | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Exan\Fenrir; | ||
|
||
use Exan\Fenrir\Component\Button\InteractionButton; | ||
use Exan\Fenrir\Constants\Events; | ||
use Exan\Fenrir\Enums\Parts\InteractionTypes; | ||
use Exan\Fenrir\Interaction\ButtonInteraction; | ||
use Exan\Fenrir\Interaction\CommandInteraction; | ||
use Exan\Fenrir\Parts\ApplicationCommand; | ||
use Exan\Fenrir\Rest\Helpers\Command\CommandBuilder; | ||
use Exan\Fenrir\Websocket\Events\InteractionCreate; | ||
use Exan\Fenrir\Websocket\Events\Ready; | ||
|
||
class InteractionHandler | ||
{ | ||
private FilteredEventEmitter $commandListener; | ||
private FilteredEventEmitter $buttonListener; | ||
|
||
/** @var array<string, callable> */ | ||
private array $handlersCommand = []; | ||
|
||
/** @var array<string, callable> */ | ||
private array $handlersButton = []; | ||
|
||
private bool $devMode = false; | ||
|
||
public function __construct(private Discord $discord, private ?string $devGuildId = null) | ||
{ | ||
if (!is_null($this->devGuildId)) { | ||
$this->devMode = true; | ||
} | ||
} | ||
|
||
public function registerCommand(CommandBuilder $commandBuilder, callable $handler): void | ||
{ | ||
if ($this->devMode) { | ||
$this->registerGuildCommand($commandBuilder, $this->devGuildId, $handler); | ||
} else { | ||
$this->registerGlobalCommand($commandBuilder, $handler); | ||
} | ||
} | ||
|
||
public function registerGuildCommand(CommandBuilder $commandBuilder, string $guildId, callable $handler): void | ||
{ | ||
$this->activateCommandListener(); | ||
|
||
/** Ready event includes Application ID */ | ||
$this->discord->gateway->events->once( | ||
Events::READY, | ||
function (Ready $ready) use ($commandBuilder, $guildId, $handler) { | ||
$this->discord->rest->guildCommand->createApplicationCommand( | ||
$ready->user->id, | ||
$guildId, | ||
$commandBuilder | ||
)->then(function (ApplicationCommand $applicationCommand) use ($handler) { | ||
$this->handlersCommand[$applicationCommand->id] = $handler; | ||
}); | ||
} | ||
); | ||
} | ||
|
||
public function registerGlobalCommand(CommandBuilder $commandBuilder, callable $handler): void | ||
{ | ||
$this->activateCommandListener(); | ||
|
||
/** Ready event includes Application ID */ | ||
$this->discord->gateway->events->once(Events::READY, function (Ready $ready) use ($commandBuilder, $handler) { | ||
$this->discord->rest->globalCommand->createApplicationCommand( | ||
$ready->user->id, | ||
$commandBuilder | ||
)->then(function (ApplicationCommand $applicationCommand) use ($handler) { | ||
$this->handlersCommand[$applicationCommand->id] = $handler; | ||
}); | ||
}); | ||
} | ||
|
||
private function activateCommandListener() | ||
{ | ||
if (isset($this->commandListener)) { | ||
return; | ||
} | ||
|
||
$this->commandListener = new FilteredEventEmitter( | ||
$this->discord->gateway->events, | ||
Events::INTERACTION_CREATE, | ||
fn (InteractionCreate $interactionCreate) => | ||
$interactionCreate->type === InteractionTypes::APPLICATION_COMMAND | ||
); | ||
|
||
$this->commandListener->on(Events::INTERACTION_CREATE, $this->handleCommandInteraction(...)); | ||
|
||
$this->commandListener->start(); | ||
} | ||
|
||
private function handleCommandInteraction(InteractionCreate $interactionCreate) | ||
{ | ||
if (!isset($this->handlersCommand[$interactionCreate->data->id])) { | ||
return; | ||
} | ||
|
||
$firedCommand = new CommandInteraction($interactionCreate, $this->discord); | ||
|
||
$this->handlersCommand[$interactionCreate->data->id]($firedCommand); | ||
} | ||
|
||
public function onButtonInteraction(InteractionButton $interactionButton, callable $action) | ||
{ | ||
$this->activateButtonListener(); | ||
|
||
$this->handlersButton[$interactionButton->customId] = $action; | ||
} | ||
|
||
private function activateButtonListener() | ||
{ | ||
if (isset($this->buttonListener)) { | ||
return; | ||
} | ||
|
||
$this->buttonListener = new FilteredEventEmitter( | ||
$this->discord->gateway->events, | ||
Events::INTERACTION_CREATE, | ||
fn (InteractionCreate $interactionCreate) => | ||
$interactionCreate->type === InteractionTypes::MESSAGE_COMPONENT | ||
&& $interactionCreate->data->component_type === 2 // @todo enum | ||
); | ||
|
||
$this->buttonListener->on(Events::INTERACTION_CREATE, $this->handleButtonInteraction(...)); | ||
|
||
$this->buttonListener->start(); | ||
} | ||
|
||
private function handleButtonInteraction(InteractionCreate $interactionCreate) | ||
{ | ||
if (!isset($this->handlersButton[$interactionCreate->data->custom_id])) { | ||
return; | ||
} | ||
|
||
$buttonInteraction = new ButtonInteraction($interactionCreate, $this->discord); | ||
|
||
$remove = $this->handlersButton[$interactionCreate->data->custom_id]($buttonInteraction); | ||
|
||
if ($remove) { | ||
unset($this->handlersButton[$interactionCreate->data->custom_id]); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Exan\Fenrir\Parts; | ||
|
||
use Exan\Fenrir\Enums\Component\ButtonStyle; | ||
use Exan\Fenrir\Enums\Parts\ChannelTypes; | ||
use Exan\Fenrir\Enums\Parts\MessageComponentTypes; | ||
use Exan\Fenrir\Parts\Emoji; | ||
|
||
class Component | ||
{ | ||
public MessageComponentTypes $type; | ||
/** | ||
* @var \Exan\Fenrir\Parts\Component[] | ||
*/ | ||
public ?array $components; | ||
public ?ButtonStyle $style; | ||
public ?string $label; | ||
public ?Emoji $emoji; | ||
public ?string $custom_id; | ||
public ?string $url; | ||
public ?bool $disabled; | ||
/** | ||
* @var \Exan\Fenrir\Parts\ComponentSelectOptions[] | ||
*/ | ||
public ?array $options; // @todo | ||
/** | ||
* @var \Exan\Fenrir\Enums\Parts\ChannelTypes[] | ||
*/ | ||
public ?array $channel_types; | ||
public ?string $placeholder; | ||
public ?int $min_values; | ||
public ?int $max_values; | ||
public ?bool $required; | ||
public ?string $value; | ||
|
||
public function setChannelTypes(array $values): void | ||
{ | ||
$this->channel_types = []; | ||
|
||
foreach ($values as $entry) { | ||
$this->channel_types[] = ChannelTypes::from($entry); | ||
} | ||
} | ||
|
||
public function setType(int $value): void | ||
{ | ||
$this->type = MessageComponentTypes::from($value); | ||
} | ||
|
||
public function setStyle(int $value): void | ||
{ | ||
$this->style = ButtonStyle::from($value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Exan\Fenrir\Parts; | ||
|
||
class ComponentSelectOptions | ||
{ | ||
public string $label; | ||
public string $value; | ||
public ?string $description; | ||
public ?Emoji $emoji; | ||
public ?bool $default; | ||
} |
Oops, something went wrong.