Skip to content

Commit

Permalink
Add .env file and update dependencies
Browse files Browse the repository at this point in the history
Delete ExampleTest.php

Skip debugging functions on Mac in ArchTest.php

Update dependencies in composer.json

Add mail, slack, and discord methods to Notifier facade

Update notifier.php configuration

Update body creation in NotifierSlack.php

Update body creation in NotifierDiscord.php
  • Loading branch information
ewilan-riviere committed Feb 2, 2024
1 parent 24c9eea commit d1e06ec
Show file tree
Hide file tree
Showing 15 changed files with 310 additions and 53 deletions.
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
NOTIFIER_DISCORD_WEBHOOK=
NOTIFIER_DISCORD_AVATAR_URL=
NOTIFIER_DISCORD_USERNAME=

NOTIFIER_SLACK_WEBHOOK=

NOTIFIER_MAIL_MAILER=smtp
NOTIFIER_MAIL_HOST=mailpit
NOTIFIER_MAIL_PORT=1025
NOTIFIER_MAIL_USERNAME=
NOTIFIER_MAIL_PASSWORD=
NOTIFIER_MAIL_ENCRYPTION=
NOTIFIER_MAIL_FROM_ADDRESS=
NOTIFIER_MAIL_FROM_NAME=
NOTIFIER_MAIL_TO_ADDRESS=
NOTIFIER_MAIL_TO_NAME=
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ phpstan.neon
testbench.yaml
vendor
node_modules
.env
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
],
"require": {
"php": "^8.1",
"illuminate/contracts": "^10.0",
"spatie/laravel-package-tools": "^1.14.0",
"illuminate/contracts": "^10.0"
"symfony/mailer": "^6.4"
},
"require-dev": {
"filament/notifications": "^3.2",
Expand Down
22 changes: 21 additions & 1 deletion config/notifier.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
<?php

// config for Kiwilan/Notifier
return [
'discord' => [
'webhook' => env('NOTIFIER_DISCORD_WEBHOOK', null),
'username' => env('NOTIFIER_DISCORD_USERNAME', null),
'avatar_url' => env('NOTIFIER_DISCORD_AVATAR_URL', null),
],

'slack' => [
'webhook' => env('NOTIFIER_SLACK_WEBHOOK', null),
],

'mail' => [
'mailer' => env('NOTIFIER_MAIL_MAILER', 'smtp'),
'host' => env('NOTIFIER_MAIL_HOST', 'mailpit'),
'port' => env('NOTIFIER_MAIL_PORT', 1025),
'username' => env('NOTIFIER_MAIL_USERNAME', null),
'password' => env('NOTIFIER_MAIL_PASSWORD', null),
'encryption' => env('NOTIFIER_MAIL_ENCRYPTION', 'tls'),
'from_address' => env('NOTIFIER_MAIL_FROM_ADDRESS', null),
'from_name' => env('NOTIFIER_MAIL_FROM_NAME', null),
'to_address' => env('NOTIFIER_MAIL_TO_ADDRESS', null),
'to_name' => env('NOTIFIER_MAIL_TO_NAME', null),
],
];
16 changes: 16 additions & 0 deletions src/Facades/Journal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Kiwilan\Notifier\Facades;

use Illuminate\Support\Facades\Facade;

/**
* @see \Kiwilan\Notifier\Journal
*/
class Journal extends Facade
{
protected static function getFacadeAccessor()
{
return \Kiwilan\Notifier\Journal::class;
}
}
4 changes: 4 additions & 0 deletions src/Facades/Notifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

/**
* @see \Kiwilan\Notifier\Notifier
*
* @method static \Kiwilan\Notifier\Notifier\NotifierMail mail()
* @method static \Kiwilan\Notifier\Notifier\NotifierSlack slack(?string $webhook = null)
* @method static \Kiwilan\Notifier\Notifier\NotifierDiscord discord(?string $webhook = null)
*/
class Notifier extends Facade
{
Expand Down
96 changes: 75 additions & 21 deletions src/Notifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
class Notifier
{
protected function __construct(
public function __construct(
protected string $type = 'unknown',
) {
}
Expand All @@ -35,11 +35,17 @@ public static function mail(): NotifierMail
*
* @see https://api.slack.com/messaging/webhooks
*/
public static function slack(string $webhook): NotifierSlack
public static function slack(?string $webhook = null): NotifierSlack
{
$self = new self();
$self->type = 'slack';

if (! $webhook) {
$webhook = config('notifier.slack.webhook');
}

$self->checkWebhook($webhook);

return NotifierSlack::make($webhook);
}

Expand All @@ -50,11 +56,17 @@ public static function slack(string $webhook): NotifierSlack
*
* @see https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
*/
public static function discord(string $webhook): NotifierDiscord
public static function discord(?string $webhook = null): NotifierDiscord
{
$self = new self();
$self->type = 'discord';

if (! $webhook) {
$webhook = config('notifier.discord.webhook');
}

$self->checkWebhook($webhook);

return NotifierDiscord::make($webhook);
}

Expand All @@ -65,9 +77,9 @@ protected function logSending(string $message): void
}
}

protected function logError(string $reason): void
protected function logError(string $reason, array $data = []): void
{
Log::error("Notifier: notification failed: {$reason}");
Log::error("Notifier: notification failed: {$reason}", $data);
}

protected function logSent(): void
Expand All @@ -77,28 +89,70 @@ protected function logSent(): void
}
}

protected function checkWebhook(?string $webhook = null): void
{
if (! $webhook) {
throw new \InvalidArgumentException("Notifier: {$this->type} webhook URL is required");
}
}

/**
* @param string|string[] $array
* @param string|string[] $message
*/
protected function arrayToString(array|string $array): string
protected function arrayToString(array|string $message): string
{
return implode(PHP_EOL, $array);
if (is_string($message)) {
return $message;
}

return implode(PHP_EOL, $message);
}

/**
* Send HTTP request.
*
* @param string $url URL to send request to
* @param array $body Request body
* @param array $headers Request headers
* @return array{status_code: int, body: string}
*/
protected function sendRequest(
string $url,
array $headers = [
'Accept' => 'application/json',
],
array $bodyJson = [],
): \Psr\Http\Message\ResponseInterface {
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $url, [
'headers' => $headers,
'json' => $bodyJson,
'http_errors' => false,
]);

return $response;
array $body = [],
array $headers = [],
bool $json = true,
): array {
$headers = [
...$headers,
$json ? 'Content-type: application/json' : 'Content-type: application/x-www-form-urlencoded',
];

$opts = [
'http' => [
'method' => 'POST',
'header' => $headers,
'content' => $json ? json_encode($body) : http_build_query($body),
],
];

$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);

if ($response === false) {
return [
'status_code' => 500,
'body' => "Failed to send request to {$url}",
];
}

$httpCode = $http_response_header[0];
$statusCode = explode(' ', $httpCode)[1];
$httpCode = (int) $statusCode;
$body = $response;

return [
'status_code' => $httpCode,
'body' => $body,
];
}
}
29 changes: 22 additions & 7 deletions src/Notifier/NotifierDiscord.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ protected function __construct(
protected ?string $message = null,
protected ?string $username = null,
protected ?string $avatarUrl = null,
protected array $body = [],
) {
}

Expand Down Expand Up @@ -46,24 +47,38 @@ public function avatarUrl(string $avatarUrl): self
return $this;
}

public function send(): bool
private function createBody(): self
{
$body = [
$this->body = [
'content' => $this->message ?? '',
];

if ($this->username) {
$body['username'] = $this->username;
$this->body['username'] = $this->username;
}

if ($this->avatarUrl) {
$body['avatar_url'] = $this->avatarUrl;
$this->body['avatar_url'] = $this->avatarUrl;
}

if (config('notifier.discord.username') && ! $this->username) {
$this->body['username'] = config('notifier.discord.username');
}

if (config('notifier.discord.avatar_url') && ! $this->avatarUrl) {
$this->body['avatar_url'] = config('notifier.discord.avatar_url');
}

$res = $this->sendRequest($this->webhook, bodyJson: $body);
return $this;
}

public function send(): bool
{
$this->createBody();
$res = $this->sendRequest($this->webhook, $this->body);

if ($res->getStatusCode() !== 204) {
$this->logError("status code {$res->getStatusCode()}, {$res->getBody()->getContents()}");
if ($res['status_code'] !== 204) {
$this->logError("status code {$res['status_code']}, {$res['body']}");

return false;
}
Expand Down
58 changes: 45 additions & 13 deletions src/Notifier/NotifierMail.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ class NotifierMail extends Notifier implements INotifier
* @param Address[] $to Array of `Address` object
*/
protected function __construct(
protected string $mailer = 'smtp',
protected string $host = 'mailpit',
protected int $port = 1025,
protected string $encryption = 'tls',
protected ?string $mailer = null,
protected ?string $host = null,
protected ?int $port = null,
protected ?string $encryption = null,
protected ?string $username = null,
protected ?string $password = null,
protected ?TransportInterface $mailTransport = null,
Expand Down Expand Up @@ -89,15 +89,43 @@ public function credentials(string $username, string $password): self
/**
* Use default mailer from `.env` file.
*/
public function auto(): self
private function auto(): self
{
$this->mailer = config('mail.mailer');
$this->host = config('mail.host');
$this->port = config('mail.port');
$this->encryption = config('mail.encryption');
$this->username = config('mail.username');
$this->password = config('mail.password');
$this->from = new Address(config('mail.from.address'), config('mail.from.name'));
if (! $this->mailer) {
$this->mailer = config('notifier.mail.mailer');
}

if (! $this->host) {
$this->host = config('notifier.mail.host');
}

if (! $this->port) {
$this->port = config('notifier.mail.port');
}

if (! $this->encryption) {
$this->encryption = config('notifier.mail.encryption');
}

if (! $this->username) {
$this->username = config('notifier.mail.username');
}

if (! $this->password) {
$this->password = config('notifier.mail.password');
}

if (! $this->from) {
$this->from = new Address(config('notifier.mail.from.address'), config('notifier.mail.from.name'));
}

if (count($this->to) === 0) {
$this->to = [new Address(config('notifier.mail.to.address'), config('notifier.mail.to.name'))];
}

if (! $this->html) {
$this->html = $this->message;
}

return $this;
}
Expand Down Expand Up @@ -157,6 +185,7 @@ public function html(array|string $html): self

public function send(): bool
{
$this->auto();
$this->mailTransport = Transport::fromDsn("{$this->mailer}://{$this->host}:{$this->port}");
$this->mailMailer = new Mailer($this->mailTransport);

Expand Down Expand Up @@ -186,10 +215,13 @@ public function send(): bool
$this->mailEmail->html($this->message);
}

dump($this);

try {
$this->mailMailer->send($this->mailEmail);
} catch (\Throwable $th) {
$this->logError($th->getMessage());
dump($th->getMessage());
$this->logError($th->getMessage(), $this->toArray());

return false;
}
Expand Down
Loading

0 comments on commit d1e06ec

Please sign in to comment.