Skip to content

Commit

Permalink
Add attachment files
Browse files Browse the repository at this point in the history
  • Loading branch information
kawax committed Mar 28, 2024
1 parent 8b2548b commit 1fe84a2
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 9 deletions.
47 changes: 41 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DiscordNotification extends Notification implements ShouldQueue
return [DiscordChannel::class];
}

public function toDiscordWebhook($notifiable): DiscordMessage
public function toDiscordWebhook(object $notifiable): DiscordMessage
{
return DiscordMessage::create(content: $this->content);
}
Expand Down Expand Up @@ -95,22 +95,59 @@ $user->notify(new DiscordNotification('test'));
### Send embeds

```php
public function toDiscordWebhook($notifiable): DiscordMessage
public function toDiscordWebhook(object $notifiable): DiscordMessage
{
return DiscordMessage::create()
->embeds([
[
'title' => 'INFO',
'description' => $this->content,
]
'url' => route('home'),
],
]);
}
```

### Send attachment files

```php
use Revolution\Laravel\Notification\DiscordWebhook\DiscordAttachment;
use Illuminate\Support\Facades\Storage;

public function toDiscordWebhook(object $notifiable): DiscordMessage
{
return DiscordMessage::create()
->embeds([
[
'title' => 'test',
'description' => $this->content,
'thumbnail' => [
'url' => 'attachment://test.jpg',
],
'image' => [
'url' => 'attachment://test2.jpg',
],
],
]);
->file(DiscordAttachment::make(
content: Storage::get('test.jpg'),
filename: 'test.jpg',
description: 'test',
filetype: 'image/jpg'
))
->file(new DiscordAttachment(
content: Storage::get('test2.jpg'),
filename: 'test2.jpg',
description: 'test2',
filetype: 'image/jpg'
));
}
```

### Send any message

```php
public function toDiscordWebhook($notifiable): DiscordMessage
public function toDiscordWebhook(object $notifiable): DiscordMessage
{
return DiscordMessage::create(content: $this->content)
->with([
Expand All @@ -119,7 +156,5 @@ $user->notify(new DiscordNotification('test'));
}
```

File upload is not supported.

## LICENSE
MIT
26 changes: 26 additions & 0 deletions src/DiscordAttachment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Revolution\Laravel\Notification\DiscordWebhook;

class DiscordAttachment
{
public function __construct(
readonly public string $content,
readonly public string $filename,
readonly public string $description,
readonly public string $filetype,
)
{
//
}

public static function make(
string $content,
string $filename,
string $description,
string $filetype,
): static
{
return new static($content, $filename, $description, $filetype);
}
}
16 changes: 15 additions & 1 deletion src/DiscordChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Revolution\Laravel\Notification\DiscordWebhook;

use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\RequestException;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Http;
Expand Down Expand Up @@ -31,6 +32,19 @@ public function send(mixed $notifiable, Notification $notification): void
return;
}

Http::post($webhook_url, $message->toArray())->throw();
Http::attach(
name: 'payload_json',
contents: json_encode($message->toArray()),
headers: ['Content-Type' => 'application/json']
)->when(filled($message->attachments()), function (PendingRequest $client) use ($message) {
foreach ($message->attachments() as $id => $attach) {
$client->attach(
name: "files[$id]",
contents: $attach->content,
filename: $attach->filename,
headers: ['Content-Type' => $attach->filetype]
);
}
})->post($webhook_url)->throw();
}
}
27 changes: 26 additions & 1 deletion src/DiscordMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

class DiscordMessage
{
/**
* @var array<DiscordAttachment>
*/
protected array $attachments = [];

protected array $options = [];

public function __construct(
Expand Down Expand Up @@ -38,6 +43,18 @@ public function embeds(array $embeds): static
return $this;
}

public function file(DiscordAttachment $attachment): static
{
$this->attachments[] = $attachment;

return $this;
}

public function attachments(): array
{
return $this->attachments;
}

public function with(array $options): static
{
$this->options = $options;
Expand All @@ -47,14 +64,22 @@ public function with(array $options): static

public function isValid(): bool
{
return Arr::hasAny($this->toArray(), ['content', 'embeds', 'components']);
return Arr::hasAny($this->toArray(), ['content', 'embeds', 'components', 'attachments']);
}

public function toArray(): array
{
$attachments = collect($this->attachments())
->map(fn (DiscordAttachment $attachment, int $id) => [
'id' => $id,
'description' => $attachment->description,
'filename' => $attachment->filename,
])->toArray();

return collect([
'content' => $this->content,
'embeds' => $this->embeds,
'attachments' => $attachments,
])->merge($this->options)
->reject(fn ($item) => blank($item))
->toArray();
Expand Down
60 changes: 59 additions & 1 deletion tests/Feature/NotificationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Client\Request;
use Illuminate\Http\Client\RequestException;
use Illuminate\Http\UploadedFile;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Revolution\Laravel\Notification\DiscordWebhook\DiscordAttachment;
use Revolution\Laravel\Notification\DiscordWebhook\DiscordChannel;
use Revolution\Laravel\Notification\DiscordWebhook\DiscordMessage;
use Tests\TestCase;
Expand All @@ -24,7 +28,10 @@ public function test_notification()
Http::assertSentCount(1);

Http::assertSent(function (Request $request) {
return $request['content'] === 'test';
return $request->isMultipart()
&& $request[0]['name'] === 'payload_json'
&& $request[0]['contents'] === '{"content":"test"}'
&& empty($request[1]);
});
}

Expand Down Expand Up @@ -89,6 +96,37 @@ public function test_message_invalid()
$this->assertFalse(DiscordMessage::create(content: '', embeds: [])->with(['test' => 'test'])->isValid());
}

public function test_notification_attachments()
{
Http::fake();

Notification::route('discord-webhook', config('services.discord.webhook'))
->notify(new TestFileNotification(content: 'test'));

Http::assertSentCount(1);

Http::assertSent(function (Request $request) {
return $request->isMultipart()
&& $request[0]['name'] === 'payload_json'
&& Str::contains($request[0]['contents'], 'test')
&& $request[1]['name'] === 'files[0]'
&& $request[1]['filename'] === 'test';
});
}

public function test_message_attachments()
{
Storage::fake('discord');

$m = DiscordMessage::create()
->file(DiscordAttachment::make(content: UploadedFile::fake()->image('test')->getContent(), filename: 'test', description: 'test', filetype: 'image/jpeg'))
->file(new DiscordAttachment(content: UploadedFile::fake()->image('test2')->getContent(), filename: 'test2', description: 'test2', filetype: 'image/jpeg'));

$this->assertIsArray($m->attachments());
$this->assertCount(2, $m->attachments());
$this->assertTrue($m->isValid());
}

public function test_user_notify()
{
Http::fake();
Expand Down Expand Up @@ -123,6 +161,26 @@ public function toDiscordWebhook(object $notifiable): DiscordMessage
}
}

class TestFileNotification extends \Illuminate\Notifications\Notification
{
public function __construct(
protected string $content,
)
{
}

public function via(object $notifiable): array
{
return [DiscordChannel::class];
}

public function toDiscordWebhook(object $notifiable): DiscordMessage
{
return DiscordMessage::create(content: $this->content)
->file(DiscordAttachment::make(content: UploadedFile::fake()->image('test')->getContent(), filename: 'test', description: 'test', filetype: 'image/jpeg'));
}
}

class TestUser extends Model
{
use Notifiable;
Expand Down

0 comments on commit 1fe84a2

Please sign in to comment.