Skip to content

Commit

Permalink
✨ Add webhook support to Messages (Fixes #52) (#73)
Browse files Browse the repository at this point in the history
* 🧑‍💻 Add a `Message::clearAuthor()` method to clear the default Message embed author/icon
* 🧑‍💻 Add a `Message::avatar()` method that aliases `avatarUrl()` for improved DX
* 🧑‍💻 Add `Message::thumbnail()` and `Message::image()` aliases for their URL equivalent
  • Loading branch information
Log1x authored Jun 5, 2024
1 parent 47b83ae commit 160483e
Showing 1 changed file with 114 additions and 3 deletions.
117 changes: 114 additions & 3 deletions src/Discord/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
use Discord\Builders\Components\ActionRow;
use Discord\Builders\Components\Button;
use Discord\Builders\MessageBuilder;
use Discord\Http\Exceptions\NoPermissionsException;
use Discord\Parts\Channel\Channel;
use Discord\Parts\Channel\Message as ChannelMessage;
use Discord\Parts\Channel\Webhook;
use Discord\Parts\Interactions\Interaction;
use Discord\Parts\User\User;
use Discord\Repository\Channel\WebhookRepository;
use Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Laracord\Laracord;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;
use Throwable;

use function React\Async\await;

class Message
{
/**
Expand Down Expand Up @@ -128,6 +134,11 @@ class Message
*/
protected array $files = [];

/**
* The message webhook.
*/
protected string|bool $webhook = false;

/**
* The default embed colors.
*/
Expand All @@ -154,8 +165,10 @@ public function __construct(?Laracord $bot)
$this->bot = $bot ?: app('bot');

$this
->authorName($this->bot->discord()->user->username)
->authorIcon($this->bot->discord()->user->avatar)
->username($username = $this->bot->discord()->username)
->avatar($avatar = $this->bot->discord()->avatar)
->authorName($username)
->authorIcon($avatar)
->success();
}

Expand All @@ -173,6 +186,8 @@ public static function make(?Laracord $bot): self
public function build(): MessageBuilder
{
$message = MessageBuilder::new()
->setUsername($this->username)
->setAvatarUrl($this->avatarUrl)
->setTts($this->tts)
->setContent($this->body)
->setComponents($this->getComponents());
Expand All @@ -197,12 +212,16 @@ public function build(): MessageBuilder
/**
* Send the message.
*/
public function send(mixed $destination = null): ?ExtendedPromiseInterface
public function send(mixed $destination = null): PromiseInterface|ExtendedPromiseInterface|null
{
if ($destination) {
$this->channel($destination);
}

if ($this->webhook) {
return $this->handleWebhook();
}

return $this->getChannel()->sendMessage($this->build());
}

Expand Down Expand Up @@ -236,6 +255,62 @@ public function sendTo(mixed $user): ?ExtendedPromiseInterface
return $user->sendMessage($this->build());
}

/**
* Send the message as a webhook.
*/
protected function handleWebhook(): ?ExtendedPromiseInterface
{
try {
/** @var WebhookRepository $webhooks */
$webhooks = await($this->getChannel()->webhooks->freshen());
} catch (NoPermissionsException) {
$this->bot->console()->error("\nMissing permission to fetch channel webhooks.");

return null;
}

if (! $webhooks) {
$this->bot->console()->error('Failed to fetch channel webhooks.');

return null;
}

if ($this->webhook === true) {
$webhook = $webhooks->find(fn (Webhook $webhook) => $webhook->name === $this->bot->discord()->username);

if (! $webhook) {
return $webhooks->save(new Webhook($this->bot->discord(), [
'name' => $this->bot->discord()->username,
]))->then(
fn (Webhook $webhook) => $webhook->execute($this->build()),
fn () => $this->bot->console()->error('Failed to create message webhook.')
);
}

return $webhook->execute($this->build());
}

$webhook = $this->getChannel()->webhooks->get('url', $this->webhook);

if (! $webhook) {
$this->bot->console()->error("Could not find webhook <fg=red>{$this->webhook}</> on channel to send message.");

return null;
}

return $webhook->execute($this->build());
}

/**
* Send the message as a webhook.
*/
public function webhook(string|bool $value = true): self
{
$this->webhook = $value;

return $this;
}

/**
* Reply to a message or interaction.
*/
Expand Down Expand Up @@ -358,6 +433,14 @@ public function content(?string $content): self
return $this;
}

/**
* Set the message avatar.
*/
public function avatar(?string $avatarUrl): self
{
return $this->avatarUrl($avatarUrl);
}

/**
* Set the message avatar URL.
*/
Expand Down Expand Up @@ -505,6 +588,16 @@ public function footerText(?string $footerText): self
return $this;
}

/**
* Set the message thumbnail URL.
*/
public function thumbnail(?string $thumbnailUrl): self
{
$this->thumbnailUrl = $thumbnailUrl;

return $this;
}

/**
* Set the message thumbnail URL.
*/
Expand All @@ -525,6 +618,16 @@ public function url(?string $url): self
return $this;
}

/**
* Set the message image URL.
*/
public function image(?string $imageUrl): self
{
$this->imageUrl = $imageUrl;

return $this;
}

/**
* Set the message image URL.
*/
Expand Down Expand Up @@ -583,6 +686,14 @@ public function authorIcon(?string $authorIcon): self
return $this;
}

/**
* Clear the message author.
*/
public function clearAuthor(): self
{
return $this->authorName('')->authorIcon('');
}

/**
* Set the message fields.
*/
Expand Down

0 comments on commit 160483e

Please sign in to comment.