From e15e6c2025d5f62c9dd9ac3494700057db07c22f Mon Sep 17 00:00:00 2001 From: Herpaderp Aldent Date: Sun, 30 Dec 2018 10:09:52 +0100 Subject: [PATCH 01/10] Some more refactoring regarding more agnostic channel integrations. --- .../Discord/DiscordNotificationChannel.php | 24 --------- .../DiscordNotificationChannelController.php | 51 +++++++++++++++++++ .../Discord/DiscordServerController.php | 26 ---------- .../SeatNotificationsController.php | 25 ++++++--- .../SlackNotificationChannelController.php | 4 +- src/config/seatnotifications.services.php | 2 +- .../views/refresh_token/channel.blade.php | 46 +++++++++-------- 7 files changed, 97 insertions(+), 81 deletions(-) delete mode 100644 src/Http/Controllers/Discord/DiscordNotificationChannel.php create mode 100644 src/Http/Controllers/Discord/DiscordNotificationChannelController.php diff --git a/src/Http/Controllers/Discord/DiscordNotificationChannel.php b/src/Http/Controllers/Discord/DiscordNotificationChannel.php deleted file mode 100644 index 5964199..0000000 --- a/src/Http/Controllers/Discord/DiscordNotificationChannel.php +++ /dev/null @@ -1,24 +0,0 @@ -back()->with('error', 'No guild_id detected, have you setup your discord bot correctly?'); + + $response = cache('herpaderp.seatnotifications.discord.channels'); + + if(is_null($response)){ + $channels = app('discord') + ->guild + ->getGuildChannels([ + 'guild.id' => (int) setting('herpaderp.seatnotifications.discord.credentials.guild_id', true), + ]); + + $response = []; + foreach ($channels as $channel) { + if($channel->type === 0) + $response[$channel->id] = $channel->name; + } + + cache(['herpaderp.seatnotifications.discord.channels' => $response], now()->addMinutes(5)); + } + + return ['discord' => $response]; + + } +} diff --git a/src/Http/Controllers/Discord/DiscordServerController.php b/src/Http/Controllers/Discord/DiscordServerController.php index c591826..ade4b32 100644 --- a/src/Http/Controllers/Discord/DiscordServerController.php +++ b/src/Http/Controllers/Discord/DiscordServerController.php @@ -278,30 +278,4 @@ public function getSocket($gateway) return new WebSocketClient($gateway); } - public function getChannels() - { - if(is_null(setting('herpaderp.seatnotifications.discord.credentials.guild_id', true))) - return redirect()->back()->with('error', 'No guild_id detected, have you setup your discord bot correctly?'); - - $response = cache('herpaderp.seatnotifications.discord.channels'); - - if(is_null($response)){ - $channels = app('discord') - ->guild - ->getGuildChannels([ - 'guild.id' => (int) setting('herpaderp.seatnotifications.discord.credentials.guild_id', true), - ]); - - $response = []; - foreach ($channels as $channel) { - if($channel->type === 0) - $response[$channel->id] = $channel->name; - } - - cache(['herpaderp.seatnotifications.discord.channels' => $response], now()->addMinutes(5)); - } - - return $response; - - } } diff --git a/src/Http/Controllers/SeatNotificationsController.php b/src/Http/Controllers/SeatNotificationsController.php index 7304c05..bc1d652 100644 --- a/src/Http/Controllers/SeatNotificationsController.php +++ b/src/Http/Controllers/SeatNotificationsController.php @@ -8,6 +8,7 @@ namespace Herpaderpaldent\Seat\SeatNotifications\Http\Controllers; +use Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Discord\DiscordNotificationChannelController; use Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Discord\DiscordServerController; use Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Slack\SlackNotificationChannelController; use Illuminate\Support\Collection; @@ -38,7 +39,7 @@ public function index() foreach ($classes as $class) { $notification_channels->push( - (new $class)->getRegistrationView() + (new $class)->getRegistrationView() ); } @@ -48,6 +49,7 @@ public function index() public function getNotifications() { $notifications = $this->getNotificationCollection(); + $available_channels = $this->getNotificationChannelCollection(); return DataTables::of($notifications) ->editColumn('notification', function ($row) { @@ -63,13 +65,10 @@ public function getNotifications() return ''; }) - ->editColumn('channel', function ($row) { - - $discord_channels = (new DiscordServerController)->getChannels(); - $slack_channels = (new SlackNotificationChannelController)->getChannels(); + ->editColumn('channel', function ($row) use ($available_channels) { if(! empty($row['channel'])) - return view($row['channel'], compact('discord_channels', 'slack_channels')); + return view($row['channel'], compact('available_channels')); return ''; }) @@ -93,4 +92,18 @@ private function getNotificationCollection() : Collection return $notifications; } + + private function getNotificationChannelCollection() : Collection + { + $notification_channels = collect([]); + $classes = config('services.seat-notification-channel'); + + foreach ($classes as $class) { + $notification_channels->push( + (new $class)->getChannels() + ); + } + + return $notification_channels; + } } diff --git a/src/Http/Controllers/Slack/SlackNotificationChannelController.php b/src/Http/Controllers/Slack/SlackNotificationChannelController.php index 07f3f3f..707656a 100644 --- a/src/Http/Controllers/Slack/SlackNotificationChannelController.php +++ b/src/Http/Controllers/Slack/SlackNotificationChannelController.php @@ -44,12 +44,12 @@ public function getChannels() } - return $response->map(function ($item) { + return ['slack' => $response->map(function ($item) { return collect([ 'name' => $item->name, 'id' => $item->id, 'private_channel' => $item->is_group, ]); - }); + })]; } } diff --git a/src/config/seatnotifications.services.php b/src/config/seatnotifications.services.php index 5e2676b..e3f01c4 100644 --- a/src/config/seatnotifications.services.php +++ b/src/config/seatnotifications.services.php @@ -3,7 +3,7 @@ return [ 'seat-notification-channel' => [ - 'discord' => Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Discord\DiscordNotificationChannel::class, + 'discord' => Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Discord\DiscordNotificationChannelController::class, 'slack' => Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Slack\SlackNotificationChannelController::class, ], 'seat-notification' => [ diff --git a/src/resources/views/refresh_token/channel.blade.php b/src/resources/views/refresh_token/channel.blade.php index c2faf01..79576f9 100644 --- a/src/resources/views/refresh_token/channel.blade.php +++ b/src/resources/views/refresh_token/channel.blade.php @@ -44,8 +44,15 @@ @@ -85,13 +92,20 @@ @@ -108,16 +122,4 @@ - - -@push('javascript') - - - -@endpush \ No newline at end of file + \ No newline at end of file From 97e162102c426f691918df9276c52f36619a6dde Mon Sep 17 00:00:00 2001 From: Herpaderp Aldent Date: Sun, 30 Dec 2018 11:15:35 +0100 Subject: [PATCH 02/10] Added permission to views --- src/config/seatnotifications.sidebar.php | 10 ++++++---- src/resources/views/refresh_token/channel.blade.php | 12 ++++++++++-- src/resources/views/refresh_token/private.blade.php | 12 ++++++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/config/seatnotifications.sidebar.php b/src/config/seatnotifications.sidebar.php index 25154da..b0f3447 100644 --- a/src/config/seatnotifications.sidebar.php +++ b/src/config/seatnotifications.sidebar.php @@ -11,16 +11,18 @@ 'name' => 'SeAT Notifications (POC)', 'icon' => 'fa-inbox', 'route_segment' => 'seatnotifications', - 'entries' => [ + 'permission' => 'seatnotifications.view', + 'entries' => [ [ 'name' => 'Notifications', 'icon' => 'fa-envelope', 'route' => 'seatnotifications.index', ], [ - 'name' => 'Configuration', - 'icon' => 'fa-gear', - 'route' => 'seatnotifications.configuration', + 'name' => 'Configuration', + 'icon' => 'fa-gear', + 'route' => 'seatnotifications.configuration', + 'permission' => 'seatnotifications.configuration', ], ], ], diff --git a/src/resources/views/refresh_token/channel.blade.php b/src/resources/views/refresh_token/channel.blade.php index 79576f9..9ae93ea 100644 --- a/src/resources/views/refresh_token/channel.blade.php +++ b/src/resources/views/refresh_token/channel.blade.php @@ -1,6 +1,10 @@ @inject('RefreshTokenController', 'Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Notifications\RefreshTokenController') -@if(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'discord', true)) +@if(! (auth()->user()->has('seatnotifications.refresh_token', false) && auth()->user()->has('seatnotifications.configuration', false))) + + Discord + +@elseif(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'discord', true)) Discord @@ -11,7 +15,11 @@ @endif -@if(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'slack', true) ) +@if(! (auth()->user()->has('seatnotifications.refresh_token', false) && auth()->user()->has('seatnotifications.configuration', false))) + + Slack + +@elseif(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'slack', true) ) Slack diff --git a/src/resources/views/refresh_token/private.blade.php b/src/resources/views/refresh_token/private.blade.php index 1c5da98..482c778 100644 --- a/src/resources/views/refresh_token/private.blade.php +++ b/src/resources/views/refresh_token/private.blade.php @@ -1,6 +1,10 @@ @inject('RefreshTokenController', 'Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Notifications\RefreshTokenController') -@if(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'discord')) +@if(! auth()->user()->has('seatnotifications.refresh_token', false)) + + Discord + +@elseif(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'discord')) Discord @@ -13,7 +17,11 @@ class="btn btn-app"> @endif -@if(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'slack')) +@if(! auth()->user()->has('seatnotifications.refresh_token', false)) + + Slack + +@elseif(! $RefreshTokenController->isSubscribed(auth()->user()->group, 'slack')) Slack From 669a16e8b47e22b107f96a1e5def3b1054e001f6 Mon Sep 17 00:00:00 2001 From: Herpaderp Aldent Date: Sun, 30 Dec 2018 13:07:32 +0100 Subject: [PATCH 03/10] Added `isUser` for Discord registration view --- src/Models/Discord/DiscordUser.php | 12 ++++++++++++ .../views/discord/registration.blade.php | 16 ++++++++++------ src/resources/views/slack/registration.blade.php | 14 ++++++++------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/Models/Discord/DiscordUser.php b/src/Models/Discord/DiscordUser.php index c314f37..ede5429 100644 --- a/src/Models/Discord/DiscordUser.php +++ b/src/Models/Discord/DiscordUser.php @@ -35,4 +35,16 @@ public function group() { return $this->belongsTo(Group::class, 'group_id', 'id'); } + + public function isUser(Group $group) + { + $slack_users = DiscordUser::all()->filter(function ($slack_user) use ($group) { + return $slack_user->group->id === $group->id; + }); + + if($slack_users->isNotEmpty()) + return true; + + return false; + } } diff --git a/src/resources/views/discord/registration.blade.php b/src/resources/views/discord/registration.blade.php index 525bf66..02c7ac5 100644 --- a/src/resources/views/discord/registration.blade.php +++ b/src/resources/views/discord/registration.blade.php @@ -1,6 +1,10 @@ - - @if(! is_null(setting('herpaderp.seatnotifications.discord.credentials.discord_id'))) - registered - @endif - Discord - \ No newline at end of file +@inject('DiscordUser', 'Herpaderpaldent\Seat\SeatNotifications\Models\Discord\DiscordUser' ) + +@if(! is_null(setting('herpaderp.seatnotifications.discord.credentials.bot_token', true))) + + @if( $DiscordUser->isUser(auth()->user()->group) ) + registered + @endif + Discord + +@endif \ No newline at end of file diff --git a/src/resources/views/slack/registration.blade.php b/src/resources/views/slack/registration.blade.php index ad8e84b..4175e85 100644 --- a/src/resources/views/slack/registration.blade.php +++ b/src/resources/views/slack/registration.blade.php @@ -1,9 +1,11 @@ @inject('SlackUser', 'Herpaderpaldent\Seat\SeatNotifications\Models\Slack\SlackUser' ) - - @if($SlackUser->isSlackUser(auth()->user()->group)) - registered - @endif - Slack - +@if(! is_null(setting('herpaderp.seatnotifications.slack.credentials.token', true))) + + @if($SlackUser->isSlackUser(auth()->user()->group)) + registered + @endif + Slack + +@endif From 624a4454df7b1fd22f84eae88ac1ddf788f027ea Mon Sep 17 00:00:00 2001 From: Herpaderp Aldent Date: Sun, 30 Dec 2018 14:44:11 +0100 Subject: [PATCH 04/10] Update ReadMe --- README.md | 118 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index ad9094d..b445777 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,109 @@ # seat-notifications -With this [SeAT](https://github.com/eveseat/seat) Package you can setup and manage notifications. This is a poc to illustrate what i meant by "Notification package needs some love". This is more of a walking skeleton then a well designed and developed solution. But from here things could take on. +With this [SeAT](https://github.com/eveseat/seat) Package you can setup and manage notifications. It is build to be expendend from within the package or from another package. Please read more about it further down. + +[![Latest Stable Version](https://poser.pugx.org/herpaderpaldent/seat-notifications/v/stable)](https://packagist.org/packages/herpaderpaldent/seat-notifications) +[![StyleCI](https://github.styleci.io/repos/140680541/shield?branch=master)](https://github.styleci.io/repos/140680541) +[![Maintainability](https://api.codeclimate.com/v1/badges/2270953cdfaa22197d78/maintainability)](https://codeclimate.com/github/herpaderpaldent/seat-notifications/maintainability) +[![License](https://poser.pugx.org/herpaderpaldent/seat-notifications/license)](https://packagist.org/packages/herpaderpaldent/seat-notifications) +[![Total Downloads](https://poser.pugx.org/herpaderpaldent/seat-notifications/downloads)](https://packagist.org/packages/herpaderpaldent/seat-notifications) + +***Important**: seat-notifications are work in progress and certainly have some bugs +please do report any findings to [seat-slack](https://eveseat-slack.herokuapp.com/) and report it as an issue*. + +## Installation + +1. cd to `/var/www/seat` +2. enter `composer require herpaderpaldent/seat-notifications` +4. run migration `php artisan migrate` + +### Enable Notification Channel +To enable `seat-notifications` functionality of sending notifications. Create a bot for your notification channel. By default seat-notifications offers two notification channels which could be extended by other packages: `slack` and `discord`: +![configuration](https://i.imgur.com/pgfuSDO.png) + +a more detailed guide on oAuth creation will follow for now the blow table must suffice: + +| Notification Channel | Redirect URLs | Comment | +|----------------------|--------------------------------------------------------------------|------------------------------------------------------------------------| +| Discord | {seat_url}/seatnotifications/discord/configuration/callback/server | This callback url is needed for the configuration of your discord bot. | +| Discord | {seat_url}/seatnotifications/discord/callback/user | This callback url is needed for the authentication of a discord user. | +| Slack | {seat_url}/seatnotifications/slack/configuration/callback/server | This callback url is needed for the configuration of your slack bot. | +| Slack | {seat_url}/seatnotifications/slack/callback/user | This callback url is needed for the authentication of a slack user. | + +***Note**: you may only configure one notification channel at your will. However, for discord you must create a bot in your application. For Slack you need to add the bot permission to your oauth scope.* + +### Setup Roles +To be able to subsripe to a notification the user needs the appropriate permission. Please setup a role that carries the needed permission and assign it to users that should be able to receive the notification. + +### Authenticate +Users need to authenticate for your setup notification channel prior to receiving notifications. they may do this in the registration box on the notification page. ## What does the package do at the moment -* Send `RefreshTokenDeleted` Notification to Discord Webhook when a Refresh Token is deleted. -* Set Discord Webhook via Form field +* Send `RefreshTokenDeleted` Notification to Discord and/or Slack when a `refresh_token` is deleted. * Using Model Observer to dispatch Notifications -* notifications are quable and send out via Horizon. +* Notifications are queueable and send out via the queue. +* The RefreshTokenNotification is able to be delivered to Channels or via DM on the users preference. + +Example: +![image](https://user-images.githubusercontent.com/6583519/50541121-0f8b3e00-0b9f-11e9-9319-1a4512376271.png) +![picture](https://i.imgur.com/img64u6.png) + +## Developing + +Most importantly: take note of [laravel's notification documentation](https://laravel.com/docs/5.5/notifications). The provided example of [RefreshTokenDeletedNotification](https://github.com/herpaderpaldent/seat-notifications/blob/master/src/Notifications/RefreshTokenDeletedNotification.php) is based upon it. Notifications are being send by using the `Notification` facade: + +``` +Notification::send($receipients, (new RefreshTokenDeletedNotification($refresh_token))); +``` + +where `$receipients` are a collection of modal that should receive the notification and `$refresh_token` is the deleted `refresh_token` that is passed to the constructor. In this example we use an Observer to send notifications: [Observer](https://github.com/herpaderpaldent/seat-notifications/blob/master/src/Observers/RefreshTokenObserver.php). + +### Add new channels + +If you have written a new notification channel that you would like to use for sending notifications to your users you might extend `config/services.php` similar to the provided example: + +``` +'seat-notification-channel' => [ + 'discord' => Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Discord\DiscordNotificationChannel::class, + ], +``` + +Your channel should extend [BaseNotificationChannel](https://github.com/herpaderpaldent/seat-notifications/blob/master/src/Http/Controllers/BaseNotificationChannel.php) -## What is it i try to achive +``` +namespace Herpaderpaldent\Seat\SeatNotifications\Http\Controllers; +use Seat\Web\Http\Controllers\Controller; +abstract class BaseNotificationChannel extends Controller +{ + abstract protected function getSettingsView(); + abstract protected function getRegistrationView(); +} +``` -![Overview](https://i.imgur.com/aW5oDjd.png) +### Add new notifications -* The basic idea derived from the webhook ability of slack or email per se to send individual notifications. I understood if we could enable users to save their SlackID and extend the current `toSlack()` method with the `to(ID)` method, the user setting up the notification would receive private messages containing the content of the notification. -This would then have been very useful f.e. if someone runs industry or PI. The user would have been notified when his/her extractor runs out. +If you want to extend the available notifications you need to extend the `seat-notification` array in `config/services.php`: -* The second idea i was aiming to achieve was: Using model observer to dispatch notifications. +``` +'seat-notification' => [ + 'refresh_token' => Herpaderpaldent\Seat\SeatNotifications\Http\Controllers\Notifications\RefreshTokenController::class, + ], +``` -* Finally: i found the notificiation package not intuitive to read and understand. This is why i recreated it in a more (for me) intuitive and readable way, which hopefully lead to more maintainable code. +Your custom notification must contain the following public functions to add your notification to the users notification list: -## What would the next steps be +``` +public function getNotification() + { + return 'seatnotifications::refresh_token.notification'; + } + public function getPrivateView() + { + return 'seatnotifications::refresh_token.private'; + } + public function getChannelView() + { + return 'seatnotifications::refresh_token.channel'; + } +``` -1. Support more channels (mail for parity) -2. create proper view with post methods and actions per type of notification: `character`, `corporation`, `seat` -3. create more observer -4. create more notifications -5. remove the test command -6. add permissions. -8. Show character notifications per character owned by user-group. -9. Implement some logic that per channel only 1 subscription is possible -10. Introduce helpers +the functions should return a string containing the name of your view that should be rendered per column. From 1a8c39b0249dbfbec4c6f0ced9e1536ab06af0d3 Mon Sep 17 00:00:00 2001 From: Herpaderp Aldent Date: Sun, 30 Dec 2018 14:45:46 +0100 Subject: [PATCH 05/10] working eraser buttons --- src/resources/views/discord/settings.blade.php | 12 ++++++------ src/resources/views/slack/settings.blade.php | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/resources/views/discord/settings.blade.php b/src/resources/views/discord/settings.blade.php index 184ea25..964a118 100644 --- a/src/resources/views/discord/settings.blade.php +++ b/src/resources/views/discord/settings.blade.php @@ -36,7 +36,7 @@ class="form-horizontal"> value="{{ setting('herpaderp.seatnotifications.discord.credentials.client_id', true) }}" readonly/> @endif - @@ -57,7 +57,7 @@ class="form-horizontal"> value="{{ setting('herpaderp.seatnotifications.discord.credentials.client_secret', true) }}" readonly/> @endif - @@ -78,7 +78,7 @@ class="form-horizontal"> value="{{ setting('herpaderp.seatnotifications.discord.credentials.bot_token', true) }}" readonly/> @endif - @@ -104,17 +104,17 @@ class="form-horizontal"> @push('javascript')