Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add webhook support to Messages (Fixes #52) #73

Merged
merged 5 commits into from
Jun 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading