diff --git a/.env.example b/.env.example index 9ce0fd9..020684a 100644 --- a/.env.example +++ b/.env.example @@ -65,4 +65,20 @@ SMS_FOURS_MESSAGE_PASSWORD=null CUSTOM_HELLOTECHNO_API_HOST="http://localhost" -TMP_FILE_LIFETIME_MIN=60 \ No newline at end of file +TMP_FILE_LIFETIME_MIN=60 + +TMP_FILE_LIFETIME_MIN=60 + +# SLACK関連 +SLACK_NOTIFICATION=false +# 取得したWebHookURL +LOG_SLACK_WEBHOOK_URL= +SLACK_WEBHOOK_URL= +# 通知を送信するチャンネル +SLACK_CHANNEL="#general" +# 通知の送信者名 +SLACK_SENDER_NAME= +# 通知の送信者アイコン画像のURL +SLACK_ICON= +# トークン +SLACK_BOT_USER_OAUTH_TOKEN= \ No newline at end of file diff --git a/app/Http/Controllers/Web/WebController.php b/app/Http/Controllers/Web/WebController.php index b7575fb..eb456f1 100644 --- a/app/Http/Controllers/Web/WebController.php +++ b/app/Http/Controllers/Web/WebController.php @@ -23,6 +23,7 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; use Illuminate\Validation\ValidationException; use LogicException; +use Slack; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -169,21 +170,27 @@ abstract class WebController extends BaseController $this->transaction->beginTransaction(); $ret = $this->run($request); + $this->transaction->commit(); + Slack::commit(); return $ret; } catch (GeneralErrorMessageException $e) { $this->transaction->rollBack(); + Slack::commit(); return $this->failedResponse([], $e->getMessage()); } catch (AppCommonException $e) { $this->transaction->rollBack(); + Slack::commit(); logs()->error(sprintf("Appエラー:%s File:%s Line:%d", $e->getMessage(), $e->getFile(), $e->getLine())); return $this->failedResponse(); } catch (ExclusiveException $e) { $this->transaction->rollBack(); + Slack::commit(); logs()->error(sprintf("排他エラー:%s", $e->getMessage())); return $this->exclusiveErrorResponse(); } catch (LogicException $e) { $this->transaction->rollBack(); + Slack::commit(); logs()->error([ sprintf("実装エラー:%s", $e->getMessage()), get_class($e), @@ -197,15 +204,18 @@ abstract class WebController extends BaseController return $this->failedResponse(); } catch (ValidationException $e) { $this->transaction->rollBack(); + Slack::commit(); return $this->validateErrorResponse($e); } catch (HttpException $e) { $this->transaction->rollBack(); + Slack::commit(); if ($e->getStatusCode() === 401) { return $this->unAuthorizedResponse(); } throw e; } catch (Exception $e) { $this->transaction->rollBack(); + Slack::commit(); logs()->error([ sprintf("例外エラー:%s", $e->getMessage()), get_class($e), diff --git a/app/Notifications/SlackNotification.php b/app/Notifications/SlackNotification.php new file mode 100644 index 0000000..c3cd61c --- /dev/null +++ b/app/Notifications/SlackNotification.php @@ -0,0 +1,76 @@ +channel = config('slack.channel'); + $this->icon = config('slack.icon'); + $this->name = config('slack.sender_name'); + $this->message = $message; + } + + /** + * Get the notification's delivery channels. + * + * @return array + */ + public function via(object $notifiable): array + { + return ['slack']; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toArray(object $notifiable): array + { + return [ + // + ]; + } + + /** + * Get the Slack representation of the notification. + * @param mixed $notifiable + * @return SlackMessage + */ + public function toSlack(object $notifiable): SlackMessage + { + return (new SlackMessage) + ->text($this->message); + } + + /** + * 各通知チャンネルで使用するキューを判断。 + * + * @return array + */ + public function viaQueues(): array + { + return [ + 'slack' => QueueName::JOB->value, + ]; + } +} diff --git a/app/Providers/SlackServiceProvider.php b/app/Providers/SlackServiceProvider.php new file mode 100644 index 0000000..bb16f0f --- /dev/null +++ b/app/Providers/SlackServiceProvider.php @@ -0,0 +1,28 @@ +app->singleton( + 'slack', + \App\Services\Slack\SlackService::class + ); + } +} diff --git a/app/Services/Slack/SlackFacade.php b/app/Services/Slack/SlackFacade.php new file mode 100644 index 0000000..52dc04e --- /dev/null +++ b/app/Services/Slack/SlackFacade.php @@ -0,0 +1,14 @@ + + */ + private Collection $messages; + + public function __construct() + { + $this->messages = new Collection(); + $this->enable = config('slack.enable', false); + } + + public function send($message = null) + { + if ($this->enable) { + $this->messages->push(new SlackNotification($message)); + } + } + + public function hasMessage(): bool + { + return $this->messages->isNotEmpty(); + } + + public function commit() + { + if (!$this->hasMessage()) return; + + foreach ($this->messages as $message) { + $this->notify($message); + logger('Slack通知登録'); + } + $this->messages->empty(); + } + + public function routeNotificationForSlack() + { + return config('slack.channel'); + } +} diff --git a/composer.json b/composer.json index 4b9de2d..0504eaf 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "h4cc/wkhtmltopdf-amd64": "0.12.x", "laravel/framework": "^10.0", "laravel/sanctum": "^3.2", + "laravel/slack-notification-channel": "^3.0", "laravel/tinker": "^2.8" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 5002687..c1390ef 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "edf71dac141191fd318aa91cb311db2a", + "content-hash": "7c99bae7aef925fa5b0dda93da7efa87", "packages": [ { "name": "barryvdh/laravel-snappy", @@ -1507,6 +1507,71 @@ }, "time": "2023-01-30T18:31:20+00:00" }, + { + "name": "laravel/slack-notification-channel", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/slack-notification-channel.git", + "reference": "20d0f6ae89aed80696e7ff2c667369a4f270c08c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/20d0f6ae89aed80696e7ff2c667369a4f270c08c", + "reference": "20d0f6ae89aed80696e7ff2c667369a4f270c08c", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^7.0", + "illuminate/http": "^9.0|^10.0", + "illuminate/notifications": "^9.0|^10.0", + "illuminate/support": "^9.0|^10.0", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^7.0|^8.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Notifications\\SlackChannelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Notifications\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Slack Notification Channel for laravel.", + "keywords": [ + "laravel", + "notifications", + "slack" + ], + "support": { + "issues": "https://github.com/laravel/slack-notification-channel/issues", + "source": "https://github.com/laravel/slack-notification-channel/tree/v3.0.0" + }, + "time": "2023-07-14T14:58:23+00:00" + }, { "name": "laravel/tinker", "version": "v2.8.1", diff --git a/config/app.php b/config/app.php index d01a11b..10cfbc3 100644 --- a/config/app.php +++ b/config/app.php @@ -197,6 +197,9 @@ return [ Barryvdh\Snappy\ServiceProvider::class, + + // カスタム追加 + App\Providers\SlackServiceProvider::class, ], /* @@ -213,6 +216,9 @@ return [ 'aliases' => Facade::defaultAliases()->merge([ // 'ExampleClass' => App\Example\ExampleClass::class, 'SnappyImage' => Barryvdh\Snappy\Facades\SnappyImage::class, + + 'Slack' => App\Services\Slack\SlackFacade::class, //追記 + ])->toArray(), ]; diff --git a/config/logging.php b/config/logging.php index 7a4dafe..c261bd2 100644 --- a/config/logging.php +++ b/config/logging.php @@ -58,6 +58,12 @@ return [ 'ignore_exceptions' => false, ], + 'app' => [ + 'driver' => 'stack', + 'channels' => ['web', 'slack'], + 'ignore_exceptions' => false, + ], + 'single' => [ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), @@ -78,7 +84,7 @@ return [ 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', - 'level' => env('LOG_LEVEL', 'critical'), + 'level' => 'error', 'replace_placeholders' => true, ], diff --git a/config/services.php b/config/services.php index 0ace530..4f599c7 100644 --- a/config/services.php +++ b/config/services.php @@ -31,4 +31,11 @@ return [ 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], + 'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_CHANNEL'), + ], + ], + ]; diff --git a/config/slack.php b/config/slack.php new file mode 100644 index 0000000..9ff6538 --- /dev/null +++ b/config/slack.php @@ -0,0 +1,9 @@ + (bool)env('SLACK_NOTIFICATION', false), + 'webhook_url' => env('SLACK_WEBHOOK_URL'), + 'channel' => env('SLACK_CHANNEL'), + 'sender_name' => env('SLACK_SENDER_NAME'), + 'icon' => env('SLACK_ICON'), +];