| @@ -65,4 +65,20 @@ SMS_FOURS_MESSAGE_PASSWORD=null | |||||
| CUSTOM_HELLOTECHNO_API_HOST="http://localhost" | CUSTOM_HELLOTECHNO_API_HOST="http://localhost" | ||||
| TMP_FILE_LIFETIME_MIN=60 | |||||
| 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= | |||||
| @@ -23,6 +23,7 @@ use Illuminate\Support\Facades\Validator; | |||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||
| use Illuminate\Validation\ValidationException; | use Illuminate\Validation\ValidationException; | ||||
| use LogicException; | use LogicException; | ||||
| use Slack; | |||||
| use Symfony\Component\HttpFoundation\BinaryFileResponse; | use Symfony\Component\HttpFoundation\BinaryFileResponse; | ||||
| use Symfony\Component\HttpKernel\Exception\HttpException; | use Symfony\Component\HttpKernel\Exception\HttpException; | ||||
| @@ -169,21 +170,27 @@ abstract class WebController extends BaseController | |||||
| $this->transaction->beginTransaction(); | $this->transaction->beginTransaction(); | ||||
| $ret = $this->run($request); | $ret = $this->run($request); | ||||
| $this->transaction->commit(); | $this->transaction->commit(); | ||||
| Slack::commit(); | |||||
| return $ret; | return $ret; | ||||
| } catch (GeneralErrorMessageException $e) { | } catch (GeneralErrorMessageException $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| return $this->failedResponse([], $e->getMessage()); | return $this->failedResponse([], $e->getMessage()); | ||||
| } catch (AppCommonException $e) { | } catch (AppCommonException $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| logs()->error(sprintf("Appエラー:%s File:%s Line:%d", $e->getMessage(), $e->getFile(), $e->getLine())); | logs()->error(sprintf("Appエラー:%s File:%s Line:%d", $e->getMessage(), $e->getFile(), $e->getLine())); | ||||
| return $this->failedResponse(); | return $this->failedResponse(); | ||||
| } catch (ExclusiveException $e) { | } catch (ExclusiveException $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| logs()->error(sprintf("排他エラー:%s", $e->getMessage())); | logs()->error(sprintf("排他エラー:%s", $e->getMessage())); | ||||
| return $this->exclusiveErrorResponse(); | return $this->exclusiveErrorResponse(); | ||||
| } catch (LogicException $e) { | } catch (LogicException $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| logs()->error([ | logs()->error([ | ||||
| sprintf("実装エラー:%s", $e->getMessage()), | sprintf("実装エラー:%s", $e->getMessage()), | ||||
| get_class($e), | get_class($e), | ||||
| @@ -197,15 +204,18 @@ abstract class WebController extends BaseController | |||||
| return $this->failedResponse(); | return $this->failedResponse(); | ||||
| } catch (ValidationException $e) { | } catch (ValidationException $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| return $this->validateErrorResponse($e); | return $this->validateErrorResponse($e); | ||||
| } catch (HttpException $e) { | } catch (HttpException $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| if ($e->getStatusCode() === 401) { | if ($e->getStatusCode() === 401) { | ||||
| return $this->unAuthorizedResponse(); | return $this->unAuthorizedResponse(); | ||||
| } | } | ||||
| throw e; | throw e; | ||||
| } catch (Exception $e) { | } catch (Exception $e) { | ||||
| $this->transaction->rollBack(); | $this->transaction->rollBack(); | ||||
| Slack::commit(); | |||||
| logs()->error([ | logs()->error([ | ||||
| sprintf("例外エラー:%s", $e->getMessage()), | sprintf("例外エラー:%s", $e->getMessage()), | ||||
| get_class($e), | get_class($e), | ||||
| @@ -0,0 +1,76 @@ | |||||
| <?php | |||||
| namespace App\Notifications; | |||||
| use App\Codes\QueueName; | |||||
| use Illuminate\Bus\Queueable; | |||||
| use Illuminate\Contracts\Queue\ShouldQueue; | |||||
| use Illuminate\Notifications\Notification; | |||||
| use Illuminate\Notifications\Slack\SlackMessage; | |||||
| class SlackNotification extends Notification implements ShouldQueue | |||||
| { | |||||
| use Queueable; | |||||
| protected $channel; | |||||
| protected $icon; | |||||
| protected $name; | |||||
| protected $message; | |||||
| /** | |||||
| * Create a new notification instance. | |||||
| */ | |||||
| public function __construct($message) | |||||
| { | |||||
| // Slackに関数する情報はconfigに定義しておく | |||||
| $this->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<int, string> | |||||
| */ | |||||
| public function via(object $notifiable): array | |||||
| { | |||||
| return ['slack']; | |||||
| } | |||||
| /** | |||||
| * Get the array representation of the notification. | |||||
| * | |||||
| * @return array<string, mixed> | |||||
| */ | |||||
| 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<string, string> | |||||
| */ | |||||
| public function viaQueues(): array | |||||
| { | |||||
| return [ | |||||
| 'slack' => QueueName::JOB->value, | |||||
| ]; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| <?php | |||||
| namespace App\Providers; | |||||
| use Illuminate\Support\ServiceProvider; | |||||
| class SlackServiceProvider extends ServiceProvider | |||||
| { | |||||
| /** | |||||
| * Register services. | |||||
| */ | |||||
| public function register(): void | |||||
| { | |||||
| // | |||||
| } | |||||
| /** | |||||
| * Bootstrap services. | |||||
| */ | |||||
| public function boot(): void | |||||
| { | |||||
| //追記 | |||||
| $this->app->singleton( | |||||
| 'slack', | |||||
| \App\Services\Slack\SlackService::class | |||||
| ); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| <?php | |||||
| namespace App\Services\Slack; | |||||
| use Illuminate\Support\Facades\Facade; | |||||
| class SlackFacade extends Facade | |||||
| { | |||||
| protected static function getFacadeAccessor() | |||||
| { | |||||
| return 'slack'; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,53 @@ | |||||
| <?php | |||||
| namespace App\Services\Slack; | |||||
| use Illuminate\Notifications\Notifiable; | |||||
| use App\Notifications\SlackNotification; | |||||
| use Illuminate\Support\Collection; | |||||
| class SlackService | |||||
| { | |||||
| use Notifiable; | |||||
| private bool $enable = false; | |||||
| /** | |||||
| * @var Collection<int,SlackNotification> | |||||
| */ | |||||
| 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'); | |||||
| } | |||||
| } | |||||
| @@ -11,6 +11,7 @@ | |||||
| "h4cc/wkhtmltopdf-amd64": "0.12.x", | "h4cc/wkhtmltopdf-amd64": "0.12.x", | ||||
| "laravel/framework": "^10.0", | "laravel/framework": "^10.0", | ||||
| "laravel/sanctum": "^3.2", | "laravel/sanctum": "^3.2", | ||||
| "laravel/slack-notification-channel": "^3.0", | |||||
| "laravel/tinker": "^2.8" | "laravel/tinker": "^2.8" | ||||
| }, | }, | ||||
| "require-dev": { | "require-dev": { | ||||
| @@ -4,7 +4,7 @@ | |||||
| "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||
| "This file is @generated automatically" | "This file is @generated automatically" | ||||
| ], | ], | ||||
| "content-hash": "edf71dac141191fd318aa91cb311db2a", | |||||
| "content-hash": "7c99bae7aef925fa5b0dda93da7efa87", | |||||
| "packages": [ | "packages": [ | ||||
| { | { | ||||
| "name": "barryvdh/laravel-snappy", | "name": "barryvdh/laravel-snappy", | ||||
| @@ -1507,6 +1507,71 @@ | |||||
| }, | }, | ||||
| "time": "2023-01-30T18:31:20+00:00" | "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", | "name": "laravel/tinker", | ||||
| "version": "v2.8.1", | "version": "v2.8.1", | ||||
| @@ -197,6 +197,9 @@ return [ | |||||
| Barryvdh\Snappy\ServiceProvider::class, | Barryvdh\Snappy\ServiceProvider::class, | ||||
| // カスタム追加 | |||||
| App\Providers\SlackServiceProvider::class, | |||||
| ], | ], | ||||
| /* | /* | ||||
| @@ -213,6 +216,9 @@ return [ | |||||
| 'aliases' => Facade::defaultAliases()->merge([ | 'aliases' => Facade::defaultAliases()->merge([ | ||||
| // 'ExampleClass' => App\Example\ExampleClass::class, | // 'ExampleClass' => App\Example\ExampleClass::class, | ||||
| 'SnappyImage' => Barryvdh\Snappy\Facades\SnappyImage::class, | 'SnappyImage' => Barryvdh\Snappy\Facades\SnappyImage::class, | ||||
| 'Slack' => App\Services\Slack\SlackFacade::class, //追記 | |||||
| ])->toArray(), | ])->toArray(), | ||||
| ]; | ]; | ||||
| @@ -58,6 +58,12 @@ return [ | |||||
| 'ignore_exceptions' => false, | 'ignore_exceptions' => false, | ||||
| ], | ], | ||||
| 'app' => [ | |||||
| 'driver' => 'stack', | |||||
| 'channels' => ['web', 'slack'], | |||||
| 'ignore_exceptions' => false, | |||||
| ], | |||||
| 'single' => [ | 'single' => [ | ||||
| 'driver' => 'single', | 'driver' => 'single', | ||||
| 'path' => storage_path('logs/laravel.log'), | 'path' => storage_path('logs/laravel.log'), | ||||
| @@ -78,7 +84,7 @@ return [ | |||||
| 'url' => env('LOG_SLACK_WEBHOOK_URL'), | 'url' => env('LOG_SLACK_WEBHOOK_URL'), | ||||
| 'username' => 'Laravel Log', | 'username' => 'Laravel Log', | ||||
| 'emoji' => ':boom:', | 'emoji' => ':boom:', | ||||
| 'level' => env('LOG_LEVEL', 'critical'), | |||||
| 'level' => 'error', | |||||
| 'replace_placeholders' => true, | 'replace_placeholders' => true, | ||||
| ], | ], | ||||
| @@ -31,4 +31,11 @@ return [ | |||||
| 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), | ||||
| ], | ], | ||||
| 'slack' => [ | |||||
| 'notifications' => [ | |||||
| 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), | |||||
| 'channel' => env('SLACK_CHANNEL'), | |||||
| ], | |||||
| ], | |||||
| ]; | ]; | ||||
| @@ -0,0 +1,9 @@ | |||||
| <?php | |||||
| return [ | |||||
| 'enable' => (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'), | |||||
| ]; | |||||