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

✨ Improve the message builder #122

Merged
merged 4 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"react/async": "^4.2",
"react/http": "^1.9",
"symfony/psr-http-message-bridge": "^7.0",
"team-reflex/discord-php": "v10.0.0-RC8"
"team-reflex/discord-php": "v10.0.0-RC10"
},
"require-dev": {
"laravel/pint": "^1.15"
Expand Down
96 changes: 75 additions & 21 deletions config/database.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
| to use as your default connection for database operations. This is
| the connection which will be utilized unless another connection
| is explicitly specified when you execute a query / statement.
|
*/

Expand All @@ -22,41 +23,59 @@
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
| Below are all of the database connections defined for your application.
| An example configuration is provided for each database system which
| is supported by Laravel. You're free to add / remove connections.
|
*/

'connections' => [

'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'url' => env('DB_URL'),
'database' => env('DB_DATABASE', config('app.env') === 'production'
? laracord_path('database.sqlite', basePath: false)
: database_path('database.sqlite')
),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
'busy_timeout' => null,
'journal_mode' => null,
'synchronous' => null,
],

'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laracord'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],

'mariadb' => [
'driver' => 'mariadb',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laracord'),
'username' => env('DB_USERNAME', 'laracord'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
Expand All @@ -66,6 +85,36 @@
]) : [],
],

'pgsql' => [
'driver' => 'pgsql',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'laracord'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'utf8'),
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],

'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DB_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'laracord'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'utf8'),
'prefix' => '',
'prefix_indexes' => true,
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
],

],

/*
Expand All @@ -75,11 +124,14 @@
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
| the migrations on disk haven't actually been run on the database.
|
*/

'migrations' => 'migrations',
'migrations' => [
'table' => 'migrations',
'update_date_on_publish' => true,
],

/*
|--------------------------------------------------------------------------
Expand All @@ -88,7 +140,7 @@
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
| such as Memcached. You may define your connection settings here.
|
*/

Expand All @@ -98,21 +150,23 @@

'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laracord'), '_').'_database_'),
],

'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],

'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
Expand Down
112 changes: 99 additions & 13 deletions src/Discord/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
use Discord\Parts\Channel\Channel;
use Discord\Parts\Channel\Message as ChannelMessage;
use Discord\Parts\Channel\Webhook;
use Discord\Parts\Guild\Sticker;
use Discord\Parts\Interactions\Interaction;
use Discord\Parts\User\User;
use Discord\Repository\Channel\WebhookRepository;
use Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Laracord\Laracord;
use React\Promise\ExtendedPromiseInterface;
Expand Down Expand Up @@ -145,6 +148,16 @@ class Message
*/
protected array $files = [];

/**
* The message attachments.
*/
protected ?Collection $attachments = null;

/**
* The message stickers.
*/
protected array $stickers = [];

/**
* The message webhook.
*/
Expand Down Expand Up @@ -198,9 +211,10 @@ public function build(): MessageBuilder
{
$message = MessageBuilder::new()
->setUsername($this->username)
->setAvatarUrl($this->avatarUrl)
->setAvatarUrl($this->getAttachment($this->avatarUrl))
->setTts($this->tts)
->setContent($this->body)
->setStickers($this->stickers)
->setComponents($this->getComponents());

if ($this->hasContent() || $this->hasFields()) {
Expand Down Expand Up @@ -383,18 +397,18 @@ public function getEmbed(): array
'color' => $this->color,
'footer' => [
'text' => $this->footerText,
'icon_url' => $this->footerIcon,
'icon_url' => $this->getAttachment($this->footerIcon),
],
'thumbnail' => [
'url' => $this->thumbnailUrl,
'url' => $this->getAttachment($this->thumbnailUrl),
],
'image' => [
'url' => $this->imageUrl,
'url' => $this->getAttachment($this->imageUrl),
],
'author' => [
'name' => $this->authorName,
'url' => $this->authorUrl,
'icon_url' => $this->authorIcon,
'icon_url' => $this->getAttachment($this->authorIcon),
],
'fields' => $this->fields,
])->filter()->all();
Expand Down Expand Up @@ -539,10 +553,30 @@ public function body(string $body = ''): self
}

/**
* Add a file from content to the message.
* Add a file using raw input, local storage, or a remote URL to the message.
*/
public function file(string $content = '', string $filename = 'file.txt'): self
public function file(string $input = '', ?string $filename = null): self
{
$isPath = (! $isUrl = Str::isUrl($input))
&& Str::length($input) <= 1024
&& ! Str::contains($input, [DIRECTORY_SEPARATOR, "\n"])
&& Str::isMatch('/\.\w+$/', $input);

$isPath = $isPath && Storage::drive('local')->exists($input);

$content = match (true) {
$isUrl => file_get_contents($input),
$isPath => Storage::drive('local')->get($input),
default => $input,
};

$filename = match (true) {
filled($filename) => $filename,
$isUrl => basename(parse_url($input, PHP_URL_PATH)),
$isPath => basename($input),
default => 'file.txt',
};

$this->files[] = [
'content' => $content,
'filename' => $filename,
Expand Down Expand Up @@ -577,6 +611,28 @@ public function hasFiles(): bool
return ! empty($this->files);
}

/**
* Retrieve the message file attachments.
*/
protected function getAttachments(): Collection
{
return $this->attachments ??= collect($this->files)->mapWithKeys(fn ($file) => [
$file['filename'] => "attachment://{$file['filename']}",
]);
}

/**
* Retrieve a message file attachment.
*/
protected function getAttachment(?string $filename = null): ?string
{
if (blank($filename)) {
return null;
}

return $this->getAttachments()->get($filename, $filename);
}

/**
* Set the message color.
*/
Expand Down Expand Up @@ -658,9 +714,7 @@ public function footerText(?string $footerText): self
*/
public function thumbnail(?string $thumbnailUrl): self
{
$this->thumbnailUrl = $thumbnailUrl;

return $this;
return $this->thumbnailUrl($thumbnailUrl);
}

/**
Expand Down Expand Up @@ -688,9 +742,7 @@ public function url(?string $url): self
*/
public function image(?string $imageUrl): self
{
$this->imageUrl = $imageUrl;

return $this;
return $this->imageUrl($imageUrl);
}

/**
Expand All @@ -703,6 +755,40 @@ public function imageUrl(?string $imageUrl): self
return $this;
}

/**
* Add a sticker to the message.
*/
public function sticker(string|Sticker $sticker): self
{
$this->stickers[] = $sticker instanceof Sticker
? $sticker->id
: $sticker;

return $this;
}

/**
* Add stickers to the message.
*/
public function stickers(array $stickers): self
{
foreach ($stickers as $sticker) {
$this->sticker($sticker);
}

return $this;
}

/**
* Clear the stickers from the message.
*/
public function clearStickers(): self
{
$this->stickers = [];

return $this;
}

/**
* Set the message timestamp.
*/
Expand Down
5 changes: 4 additions & 1 deletion src/Laracord.php
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,10 @@ public function handleSafe(string $name, callable $callback): mixed
return $callback();
} catch (Throwable $e) {
$this->console()->error("An error occurred in <fg=red>{$name}</>.");
$this->console()->outputComponents()->bulletList([$e->getMessage()]);

$this->console()->outputComponents()->bulletList([
sprintf('%s in %s:%d', $e->getMessage(), $e->getFile(), $e->getLine()),
]);
}

return null;
Expand Down
Loading