Updated to v1.3.0

Added slack webhook notifications
This commit is contained in:
Henry Whitaker
2020-04-27 19:32:18 +01:00
parent eb95e062a9
commit 89dce90211
25 changed files with 1255 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
# Speedtest Tracker
[![Docker pulls](https://img.shields.io/docker/pulls/henrywhitaker3/speedtest-tracker)](https://hub.docker.com/r/henrywhitaker3/speedtest-tracker) [![last_commit](https://img.shields.io/github/last-commit/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) [![issues](https://img.shields.io/github/issues/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/issues) [![commit_freq](https://img.shields.io/github/commit-activity/m/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) ![version](https://img.shields.io/badge/version-v1.2.9-success) [![license](https://img.shields.io/github/license/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/blob/master/LICENSE)
[![Docker pulls](https://img.shields.io/docker/pulls/henrywhitaker3/speedtest-tracker)](https://hub.docker.com/r/henrywhitaker3/speedtest-tracker) [![last_commit](https://img.shields.io/github/last-commit/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) [![issues](https://img.shields.io/github/issues/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/issues) [![commit_freq](https://img.shields.io/github/commit-activity/m/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) ![version](https://img.shields.io/badge/version-v1.3.0-success) [![license](https://img.shields.io/github/license/henrywhitaker3/Speedtest-Tracker)](https://github.com/henrywhitaker3/Speedtest-Tracker/blob/master/LICENSE)
This program runs a speedtest check every hour and graphs the results. The back-end is written in [Laravel](https://laravel.com/) and the front-end uses [React](https://reactjs.org/). It uses the [speedtest-cli](https://github.com/sivel/speedtest-cli) package to get the data and uses [Chart.js](https://www.chartjs.org/) to plot the results.
@@ -19,10 +19,22 @@ docker create \
--name=speedtest \
-p 8765:80 \
-v /path/to/data:/config \
-e SLACK_WEBHOOK=webhook `#optional` \
--restart unless-stopped \
henrywhitaker3/speedtest-tracker
```
## Parameters
Container images are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate `<external>:<internal>` respectively. For example, `-p 8080:80` would expose port `80` from inside the container to be accessible from the host's IP on port `8080` outside the container.
| Parameter | Function |
| :----: | --- |
| `-p 8765:80` | Exposes the webserver on port 8765 |
| `-e SLACK_WEBHOOK` | Put a slack webhook here to get slack notifications when a speedtest is run. To use discord webhooks, just append `/slack` to the end of your discord webhook URL |
| `-v /config` | All the config files reside here. |
## Getting the Image
To get the base image, you have 2 options:

View File

@@ -14,6 +14,12 @@ else
cd /app/site && php artisan key:generate
fi
if [ -z ${SLACK_WEBHOOK+x} ]; then
echo "Slack webhook is unset"
else
sed "s,SLACK_WEBHOOK=.*,SLACK_WEBHOOK=$SLACK_WEBHOOK," -i.bak .env
fi
cd /app/site && php artisan migrate
cd /config
@@ -22,4 +28,4 @@ mkdir -p logs
chown -R application /config
chmod 775 -R /config
echo "* * * * * cd /app/site/ && php artisan schedule:run >> /dev/null 2>&1" | crontab -
echo "* * * * * cd /app/site/ && php artisan schedule:run >> /dev/null 2>&1" | crontab -

View File

@@ -21,3 +21,5 @@ SPEEDTEST_PASSWORD=
# Number of days you stay logged in for
REMEMBER_DAYS=30
SLACK_WEBHOOK=

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class SpeedtestCompleteEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($speedtest)
{
$this->speedtest = $speedtest;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Jobs;
use App\Events\SpeedtestCompleteEvent;
use App\Helpers\SpeedtestHelper;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -31,7 +32,8 @@ class SpeedtestJob implements ShouldQueue
public function handle()
{
$output = shell_exec('speedtest-cli');
return SpeedtestHelper::runSpeedtest($output);
$speedtest = SpeedtestHelper::runSpeedtest($output);
event(new SpeedtestCompleteEvent($speedtest));
return $speedtest;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Listeners;
use App\Notifications\SpeedtestComplete;
use Exception;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class SpeedtestCompleteListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
if(env('SLACK_WEBHOOK')) {
$data = $event->speedtest;
try {
Notification::route('slack', env('SLACK_WEBHOOK'))
->notify(new SpeedtestComplete($data));
} catch(Exception $e) {
Log::notice('Your sleck webhook is invalid');
Log::notice($e);
}
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\SlackMessage;
class SpeedtestComplete extends Notification
{
use Queueable;
protected $speedtest;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($speedtest)
{
$this->speedtest = $speedtest;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['slack'];
}
public function toSlack($notifiable)
{
$speedtest = $this->speedtest;
return (new SlackMessage)
->warning()
->attachment(function ($attachment) use ($speedtest) {
$attachment->title('New speedtest')
->fields([
'Ping' => number_format((float)$speedtest->ping, 1, '.', '') . ' ms',
'Download' => number_format((float)$speedtest->download, 1, '.', '') . ' Mbit/s',
'Upload' => number_format((float)$speedtest->upload, 1, '.', '') . ' Mbit/s',
]);
});
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

View File

@@ -2,6 +2,8 @@
namespace App\Providers;
use App\Events\SpeedtestCompleteEvent;
use App\Listeners\SpeedtestCompleteListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -18,6 +20,9 @@ class EventServiceProvider extends ServiceProvider
Registered::class => [
SendEmailVerificationNotification::class,
],
SpeedtestCompleteEvent::class => [
SpeedtestCompleteListener::class,
],
];
/**

View File

@@ -1,4 +1,10 @@
{
"1.3.0": [
{
"description": "Added discord notifications",
"link": ""
}
],
"1.2.9": [
{
"description": "Updated laravel framework",

View File

@@ -13,6 +13,7 @@
"fruitcake/laravel-cors": "^1.0",
"guzzlehttp/guzzle": "^6.3",
"laravel/framework": "^7.0",
"laravel/slack-notification-channel": "^2.0",
"laravel/tinker": "^2.0",
"laravel/ui": "^2.0",
"tymon/jwt-auth": "^1.0"

View File

@@ -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": "376dfceee60ad21d948e52a97a25faaf",
"content-hash": "7de35f5352b6b3050eb2e7cdf6fd1fec",
"packages": [
{
"name": "asm89/stack-cors",
@@ -841,6 +841,63 @@
],
"time": "2020-04-24T17:21:56+00:00"
},
{
"name": "laravel/slack-notification-channel",
"version": "v2.0.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git",
"reference": "ecc90a70791195d6f5e20b2732a5eb1eb9619d10"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/ecc90a70791195d6f5e20b2732a5eb1eb9619d10",
"reference": "ecc90a70791195d6f5e20b2732a5eb1eb9619d10",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0",
"illuminate/notifications": "~5.8.0|^6.0|^7.0",
"php": "^7.1.3"
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-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"
],
"time": "2019-08-27T14:40:26+00:00"
},
{
"name": "laravel/tinker",
"version": "v2.4.0",

View File

@@ -7,7 +7,7 @@ return [
|--------------------------------------------------------------------------
*/
'version' => '1.2.9',
'version' => '1.3.0',
/*
|--------------------------------------------------------------------------

View File

@@ -11,6 +11,7 @@ return array(
'App\\Console\\Commands\\SpeedtestCommand' => $baseDir . '/app/Console/Commands/SpeedtestCommand.php',
'App\\Console\\Commands\\SpeedtestLatestCommand' => $baseDir . '/app/Console/Commands/SpeedtestLatestCommand.php',
'App\\Console\\Kernel' => $baseDir . '/app/Console/Kernel.php',
'App\\Events\\SpeedtestCompleteEvent' => $baseDir . '/app/Events/SpeedtestCompleteEvent.php',
'App\\Exceptions\\Handler' => $baseDir . '/app/Exceptions/Handler.php',
'App\\Facades\\UpdaterFacade' => $baseDir . '/app/Facades/UpdaterFacade.php',
'App\\Helpers\\BackupHelper' => $baseDir . '/app/Helpers/BackupHelper.php',
@@ -33,6 +34,8 @@ return array(
'App\\Http\\Middleware\\TrustProxies' => $baseDir . '/app/Http/Middleware/TrustProxies.php',
'App\\Http\\Middleware\\VerifyCsrfToken' => $baseDir . '/app/Http/Middleware/VerifyCsrfToken.php',
'App\\Jobs\\SpeedtestJob' => $baseDir . '/app/Jobs/SpeedtestJob.php',
'App\\Listeners\\SpeedtestCompleteListener' => $baseDir . '/app/Listeners/SpeedtestCompleteListener.php',
'App\\Notifications\\SpeedtestComplete' => $baseDir . '/app/Notifications/SpeedtestComplete.php',
'App\\Providers\\AppServiceProvider' => $baseDir . '/app/Providers/AppServiceProvider.php',
'App\\Providers\\AuthServiceProvider' => $baseDir . '/app/Providers/AuthServiceProvider.php',
'App\\Providers\\BroadcastServiceProvider' => $baseDir . '/app/Providers/BroadcastServiceProvider.php',
@@ -1523,6 +1526,7 @@ return array(
'Illuminate\\Notifications\\Channels\\BroadcastChannel' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Channels/BroadcastChannel.php',
'Illuminate\\Notifications\\Channels\\DatabaseChannel' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Channels/DatabaseChannel.php',
'Illuminate\\Notifications\\Channels\\MailChannel' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php',
'Illuminate\\Notifications\\Channels\\SlackWebhookChannel' => $vendorDir . '/laravel/slack-notification-channel/src/Channels/SlackWebhookChannel.php',
'Illuminate\\Notifications\\Console\\NotificationTableCommand' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Console/NotificationTableCommand.php',
'Illuminate\\Notifications\\DatabaseNotification' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/DatabaseNotification.php',
'Illuminate\\Notifications\\DatabaseNotificationCollection' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/DatabaseNotificationCollection.php',
@@ -1535,12 +1539,16 @@ return array(
'Illuminate\\Notifications\\Messages\\DatabaseMessage' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Messages/DatabaseMessage.php',
'Illuminate\\Notifications\\Messages\\MailMessage' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Messages/MailMessage.php',
'Illuminate\\Notifications\\Messages\\SimpleMessage' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Messages/SimpleMessage.php',
'Illuminate\\Notifications\\Messages\\SlackAttachment' => $vendorDir . '/laravel/slack-notification-channel/src/Messages/SlackAttachment.php',
'Illuminate\\Notifications\\Messages\\SlackAttachmentField' => $vendorDir . '/laravel/slack-notification-channel/src/Messages/SlackAttachmentField.php',
'Illuminate\\Notifications\\Messages\\SlackMessage' => $vendorDir . '/laravel/slack-notification-channel/src/Messages/SlackMessage.php',
'Illuminate\\Notifications\\Notifiable' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Notifiable.php',
'Illuminate\\Notifications\\Notification' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/Notification.php',
'Illuminate\\Notifications\\NotificationSender' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/NotificationSender.php',
'Illuminate\\Notifications\\NotificationServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/NotificationServiceProvider.php',
'Illuminate\\Notifications\\RoutesNotifications' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php',
'Illuminate\\Notifications\\SendQueuedNotifications' => $vendorDir . '/laravel/framework/src/Illuminate/Notifications/SendQueuedNotifications.php',
'Illuminate\\Notifications\\SlackChannelServiceProvider' => $vendorDir . '/laravel/slack-notification-channel/src/SlackChannelServiceProvider.php',
'Illuminate\\Pagination\\AbstractPaginator' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/AbstractPaginator.php',
'Illuminate\\Pagination\\LengthAwarePaginator' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/LengthAwarePaginator.php',
'Illuminate\\Pagination\\PaginationServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Pagination/PaginationServiceProvider.php',

View File

@@ -18,9 +18,9 @@ return array(
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'9cdd7b9056abc3081735233ba9dd9c7f' => $vendorDir . '/facade/flare-client-php/src/helpers.php',

View File

@@ -8,7 +8,7 @@ $baseDir = dirname($vendorDir);
return array(
'voku\\tests\\' => array($vendorDir . '/voku/portable-ascii/tests'),
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-common/src'),
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Whoops\\' => array($vendorDir . '/filp/whoops/src/Whoops'),
'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
@@ -58,6 +58,7 @@ return array(
'Lcobucci\\JWT\\' => array($vendorDir . '/lcobucci/jwt/src'),
'Laravel\\Ui\\' => array($vendorDir . '/laravel/ui/src'),
'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'),
'Illuminate\\Notifications\\' => array($vendorDir . '/laravel/slack-notification-channel/src'),
'Illuminate\\Foundation\\Auth\\' => array($vendorDir . '/laravel/ui/auth-backend'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),

View File

@@ -19,9 +19,9 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php',
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php',
'9cdd7b9056abc3081735233ba9dd9c7f' => __DIR__ . '/..' . '/facade/flare-client-php/src/helpers.php',
@@ -122,6 +122,7 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
),
'I' =>
array (
'Illuminate\\Notifications\\' => 25,
'Illuminate\\Foundation\\Auth\\' => 27,
'Illuminate\\' => 11,
),
@@ -179,9 +180,9 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
),
'phpDocumentor\\Reflection\\' =>
array (
0 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
2 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
),
'XdgBaseDir\\' =>
array (
@@ -379,6 +380,10 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
array (
0 => __DIR__ . '/..' . '/laravel/tinker/src',
),
'Illuminate\\Notifications\\' =>
array (
0 => __DIR__ . '/..' . '/laravel/slack-notification-channel/src',
),
'Illuminate\\Foundation\\Auth\\' =>
array (
0 => __DIR__ . '/..' . '/laravel/ui/auth-backend',
@@ -496,6 +501,7 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
'App\\Console\\Commands\\SpeedtestCommand' => __DIR__ . '/../..' . '/app/Console/Commands/SpeedtestCommand.php',
'App\\Console\\Commands\\SpeedtestLatestCommand' => __DIR__ . '/../..' . '/app/Console/Commands/SpeedtestLatestCommand.php',
'App\\Console\\Kernel' => __DIR__ . '/../..' . '/app/Console/Kernel.php',
'App\\Events\\SpeedtestCompleteEvent' => __DIR__ . '/../..' . '/app/Events/SpeedtestCompleteEvent.php',
'App\\Exceptions\\Handler' => __DIR__ . '/../..' . '/app/Exceptions/Handler.php',
'App\\Facades\\UpdaterFacade' => __DIR__ . '/../..' . '/app/Facades/UpdaterFacade.php',
'App\\Helpers\\BackupHelper' => __DIR__ . '/../..' . '/app/Helpers/BackupHelper.php',
@@ -518,6 +524,8 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
'App\\Http\\Middleware\\TrustProxies' => __DIR__ . '/../..' . '/app/Http/Middleware/TrustProxies.php',
'App\\Http\\Middleware\\VerifyCsrfToken' => __DIR__ . '/../..' . '/app/Http/Middleware/VerifyCsrfToken.php',
'App\\Jobs\\SpeedtestJob' => __DIR__ . '/../..' . '/app/Jobs/SpeedtestJob.php',
'App\\Listeners\\SpeedtestCompleteListener' => __DIR__ . '/../..' . '/app/Listeners/SpeedtestCompleteListener.php',
'App\\Notifications\\SpeedtestComplete' => __DIR__ . '/../..' . '/app/Notifications/SpeedtestComplete.php',
'App\\Providers\\AppServiceProvider' => __DIR__ . '/../..' . '/app/Providers/AppServiceProvider.php',
'App\\Providers\\AuthServiceProvider' => __DIR__ . '/../..' . '/app/Providers/AuthServiceProvider.php',
'App\\Providers\\BroadcastServiceProvider' => __DIR__ . '/../..' . '/app/Providers/BroadcastServiceProvider.php',
@@ -2008,6 +2016,7 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
'Illuminate\\Notifications\\Channels\\BroadcastChannel' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Channels/BroadcastChannel.php',
'Illuminate\\Notifications\\Channels\\DatabaseChannel' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Channels/DatabaseChannel.php',
'Illuminate\\Notifications\\Channels\\MailChannel' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php',
'Illuminate\\Notifications\\Channels\\SlackWebhookChannel' => __DIR__ . '/..' . '/laravel/slack-notification-channel/src/Channels/SlackWebhookChannel.php',
'Illuminate\\Notifications\\Console\\NotificationTableCommand' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Console/NotificationTableCommand.php',
'Illuminate\\Notifications\\DatabaseNotification' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/DatabaseNotification.php',
'Illuminate\\Notifications\\DatabaseNotificationCollection' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/DatabaseNotificationCollection.php',
@@ -2020,12 +2029,16 @@ class ComposerStaticInit5f38f71e2023aa5bb7a383f21d759786
'Illuminate\\Notifications\\Messages\\DatabaseMessage' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Messages/DatabaseMessage.php',
'Illuminate\\Notifications\\Messages\\MailMessage' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Messages/MailMessage.php',
'Illuminate\\Notifications\\Messages\\SimpleMessage' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Messages/SimpleMessage.php',
'Illuminate\\Notifications\\Messages\\SlackAttachment' => __DIR__ . '/..' . '/laravel/slack-notification-channel/src/Messages/SlackAttachment.php',
'Illuminate\\Notifications\\Messages\\SlackAttachmentField' => __DIR__ . '/..' . '/laravel/slack-notification-channel/src/Messages/SlackAttachmentField.php',
'Illuminate\\Notifications\\Messages\\SlackMessage' => __DIR__ . '/..' . '/laravel/slack-notification-channel/src/Messages/SlackMessage.php',
'Illuminate\\Notifications\\Notifiable' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Notifiable.php',
'Illuminate\\Notifications\\Notification' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/Notification.php',
'Illuminate\\Notifications\\NotificationSender' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/NotificationSender.php',
'Illuminate\\Notifications\\NotificationServiceProvider' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/NotificationServiceProvider.php',
'Illuminate\\Notifications\\RoutesNotifications' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php',
'Illuminate\\Notifications\\SendQueuedNotifications' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Notifications/SendQueuedNotifications.php',
'Illuminate\\Notifications\\SlackChannelServiceProvider' => __DIR__ . '/..' . '/laravel/slack-notification-channel/src/SlackChannelServiceProvider.php',
'Illuminate\\Pagination\\AbstractPaginator' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Pagination/AbstractPaginator.php',
'Illuminate\\Pagination\\LengthAwarePaginator' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Pagination/LengthAwarePaginator.php',
'Illuminate\\Pagination\\PaginationServiceProvider' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Pagination/PaginationServiceProvider.php',

View File

@@ -1258,6 +1258,65 @@
"laravel"
]
},
{
"name": "laravel/slack-notification-channel",
"version": "v2.0.2",
"version_normalized": "2.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git",
"reference": "ecc90a70791195d6f5e20b2732a5eb1eb9619d10"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/ecc90a70791195d6f5e20b2732a5eb1eb9619d10",
"reference": "ecc90a70791195d6f5e20b2732a5eb1eb9619d10",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0",
"illuminate/notifications": "~5.8.0|^6.0|^7.0",
"php": "^7.1.3"
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.0|^8.0"
},
"time": "2019-08-27T14:40:26+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
},
"laravel": {
"providers": [
"Illuminate\\Notifications\\SlackChannelServiceProvider"
]
}
},
"installation-source": "dist",
"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"
]
},
{
"name": "laravel/tinker",
"version": "v2.4.0",

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Taylor Otwell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,14 @@
# Laravel Slack Notification Channel
<a href="https://travis-ci.org/laravel/slack-notification-channel"><img src="https://travis-ci.org/laravel/slack-notification-channel.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/slack-notification-channel"><img src="https://poser.pugx.org/laravel/slack-notification-channel/d/total.svg" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/slack-notification-channel"><img src="https://poser.pugx.org/laravel/slack-notification-channel/v/stable.svg" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/slack-notification-channel"><img src="https://poser.pugx.org/laravel/slack-notification-channel/license.svg" alt="License"></a>
## Official Documentation
Documentation for Laravel Slack Notification Channel can be found on the [Laravel website](https://laravel.com/docs/notifications#slack-notifications).
## License
Laravel Slack Notification Channel is open-sourced software licensed under the [MIT license](LICENSE.md).

View File

@@ -0,0 +1,46 @@
{
"name": "laravel/slack-notification-channel",
"description": "Slack Notification Channel for laravel.",
"keywords": ["laravel", "notifications", "slack"],
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"require": {
"php": "^7.1.3",
"guzzlehttp/guzzle": "^6.0",
"illuminate/notifications": "~5.8.0|^6.0|^7.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.0|^8.0"
},
"autoload": {
"psr-4": {
"Illuminate\\Notifications\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Illuminate\\Tests\\Notifications\\": "tests/"
}
},
"config": {
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
},
"laravel": {
"providers": [
"Illuminate\\Notifications\\SlackChannelServiceProvider"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Illuminate\Notifications\Channels;
use GuzzleHttp\Client as HttpClient;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Messages\SlackAttachment;
use Illuminate\Notifications\Messages\SlackAttachmentField;
class SlackWebhookChannel
{
/**
* The HTTP client instance.
*
* @var \GuzzleHttp\Client
*/
protected $http;
/**
* Create a new Slack channel instance.
*
* @param \GuzzleHttp\Client $http
* @return void
*/
public function __construct(HttpClient $http)
{
$this->http = $http;
}
/**
* Send the given notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return \Psr\Http\Message\ResponseInterface|null
*/
public function send($notifiable, Notification $notification)
{
if (! $url = $notifiable->routeNotificationFor('slack', $notification)) {
return;
}
return $this->http->post($url, $this->buildJsonPayload(
$notification->toSlack($notifiable)
));
}
/**
* Build up a JSON payload for the Slack webhook.
*
* @param \Illuminate\Notifications\Messages\SlackMessage $message
* @return array
*/
protected function buildJsonPayload(SlackMessage $message)
{
$optionalFields = array_filter([
'channel' => data_get($message, 'channel'),
'icon_emoji' => data_get($message, 'icon'),
'icon_url' => data_get($message, 'image'),
'link_names' => data_get($message, 'linkNames'),
'unfurl_links' => data_get($message, 'unfurlLinks'),
'unfurl_media' => data_get($message, 'unfurlMedia'),
'username' => data_get($message, 'username'),
]);
return array_merge([
'json' => array_merge([
'text' => $message->content,
'attachments' => $this->attachments($message),
], $optionalFields),
], $message->http);
}
/**
* Format the message's attachments.
*
* @param \Illuminate\Notifications\Messages\SlackMessage $message
* @return array
*/
protected function attachments(SlackMessage $message)
{
return collect($message->attachments)->map(function ($attachment) use ($message) {
return array_filter([
'actions' => $attachment->actions,
'author_icon' => $attachment->authorIcon,
'author_link' => $attachment->authorLink,
'author_name' => $attachment->authorName,
'color' => $attachment->color ?: $message->color(),
'fallback' => $attachment->fallback,
'fields' => $this->fields($attachment),
'footer' => $attachment->footer,
'footer_icon' => $attachment->footerIcon,
'image_url' => $attachment->imageUrl,
'mrkdwn_in' => $attachment->markdown,
'pretext' => $attachment->pretext,
'text' => $attachment->content,
'thumb_url' => $attachment->thumbUrl,
'title' => $attachment->title,
'title_link' => $attachment->url,
'ts' => $attachment->timestamp,
]);
})->all();
}
/**
* Format the attachment's fields.
*
* @param \Illuminate\Notifications\Messages\SlackAttachment $attachment
* @return array
*/
protected function fields(SlackAttachment $attachment)
{
return collect($attachment->fields)->map(function ($value, $key) {
if ($value instanceof SlackAttachmentField) {
return $value->toArray();
}
return ['title' => $key, 'value' => $value, 'short' => true];
})->values()->all();
}
}

View File

@@ -0,0 +1,348 @@
<?php
namespace Illuminate\Notifications\Messages;
use Illuminate\Support\InteractsWithTime;
class SlackAttachment
{
use InteractsWithTime;
/**
* The attachment's title.
*
* @var string
*/
public $title;
/**
* The attachment's URL.
*
* @var string
*/
public $url;
/**
* The attachment's pretext.
*
* @var string
*/
public $pretext;
/**
* The attachment's text content.
*
* @var string
*/
public $content;
/**
* A plain-text summary of the attachment.
*
* @var string
*/
public $fallback;
/**
* The attachment's color.
*
* @var string
*/
public $color;
/**
* The attachment's fields.
*
* @var array
*/
public $fields;
/**
* The fields containing markdown.
*
* @var array
*/
public $markdown;
/**
* The attachment's image url.
*
* @var string
*/
public $imageUrl;
/**
* The attachment's thumb url.
*
* @var string
*/
public $thumbUrl;
/**
* The attachment's actions.
*
* @var array
*/
public $actions = [];
/**
* The attachment author's name.
*
* @var string
*/
public $authorName;
/**
* The attachment author's link.
*
* @var string
*/
public $authorLink;
/**
* The attachment author's icon.
*
* @var string
*/
public $authorIcon;
/**
* The attachment's footer.
*
* @var string
*/
public $footer;
/**
* The attachment's footer icon.
*
* @var string
*/
public $footerIcon;
/**
* The attachment's timestamp.
*
* @var int
*/
public $timestamp;
/**
* Set the title of the attachment.
*
* @param string $title
* @param string|null $url
* @return $this
*/
public function title($title, $url = null)
{
$this->title = $title;
$this->url = $url;
return $this;
}
/**
* Set the pretext of the attachment.
*
* @param string $pretext
* @return $this
*/
public function pretext($pretext)
{
$this->pretext = $pretext;
return $this;
}
/**
* Set the content (text) of the attachment.
*
* @param string $content
* @return $this
*/
public function content($content)
{
$this->content = $content;
return $this;
}
/**
* A plain-text summary of the attachment.
*
* @param string $fallback
* @return $this
*/
public function fallback($fallback)
{
$this->fallback = $fallback;
return $this;
}
/**
* Set the color of the attachment.
*
* @param string $color
* @return $this
*/
public function color($color)
{
$this->color = $color;
return $this;
}
/**
* Add a field to the attachment.
*
* @param \Closure|string $title
* @param string $content
* @return $this
*/
public function field($title, $content = '')
{
if (is_callable($title)) {
$callback = $title;
$callback($attachmentField = new SlackAttachmentField);
$this->fields[] = $attachmentField;
return $this;
}
$this->fields[$title] = $content;
return $this;
}
/**
* Set the fields of the attachment.
*
* @param array $fields
* @return $this
*/
public function fields(array $fields)
{
$this->fields = $fields;
return $this;
}
/**
* Set the fields containing markdown.
*
* @param array $fields
* @return $this
*/
public function markdown(array $fields)
{
$this->markdown = $fields;
return $this;
}
/**
* Set the image URL.
*
* @param string $url
* @return $this
*/
public function image($url)
{
$this->imageUrl = $url;
return $this;
}
/**
* Set the URL to the attachment thumbnail.
*
* @param string $url
* @return $this
*/
public function thumb($url)
{
$this->thumbUrl = $url;
return $this;
}
/**
* Add an action (button) under the attachment.
*
* @param string $title
* @param string $url
* @param string $style
* @return $this
*/
public function action($title, $url, $style = '')
{
$this->actions[] = [
'type' => 'button',
'text' => $title,
'url' => $url,
'style' => $style,
];
return $this;
}
/**
* Set the author of the attachment.
*
* @param string $name
* @param string|null $link
* @param string|null $icon
* @return $this
*/
public function author($name, $link = null, $icon = null)
{
$this->authorName = $name;
$this->authorLink = $link;
$this->authorIcon = $icon;
return $this;
}
/**
* Set the footer content.
*
* @param string $footer
* @return $this
*/
public function footer($footer)
{
$this->footer = $footer;
return $this;
}
/**
* Set the footer icon.
*
* @param string $icon
* @return $this
*/
public function footerIcon($icon)
{
$this->footerIcon = $icon;
return $this;
}
/**
* Set the timestamp.
*
* @param \DateTimeInterface|\DateInterval|int $timestamp
* @return $this
*/
public function timestamp($timestamp)
{
$this->timestamp = $this->availableAt($timestamp);
return $this;
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace Illuminate\Notifications\Messages;
class SlackAttachmentField
{
/**
* The title field of the attachment field.
*
* @var string
*/
protected $title;
/**
* The content of the attachment field.
*
* @var string
*/
protected $content;
/**
* Whether the content is short.
*
* @var bool
*/
protected $short = true;
/**
* Set the title of the field.
*
* @param string $title
* @return $this
*/
public function title($title)
{
$this->title = $title;
return $this;
}
/**
* Set the content of the field.
*
* @param string $content
* @return $this
*/
public function content($content)
{
$this->content = $content;
return $this;
}
/**
* Indicates that the content should not be displayed side-by-side with other fields.
*
* @return $this
*/
public function long()
{
$this->short = false;
return $this;
}
/**
* Get the array representation of the attachment field.
*
* @return array
*/
public function toArray()
{
return [
'title' => $this->title,
'value' => $this->content,
'short' => $this->short,
];
}
}

View File

@@ -0,0 +1,273 @@
<?php
namespace Illuminate\Notifications\Messages;
use Closure;
class SlackMessage
{
/**
* The "level" of the notification (info, success, warning, error).
*
* @var string
*/
public $level = 'info';
/**
* The username to send the message from.
*
* @var string|null
*/
public $username;
/**
* The user emoji icon for the message.
*
* @var string|null
*/
public $icon;
/**
* The user image icon for the message.
*
* @var string|null
*/
public $image;
/**
* The channel to send the message on.
*
* @var string|null
*/
public $channel;
/**
* The text content of the message.
*
* @var string
*/
public $content;
/**
* Indicates if channel names and usernames should be linked.
*
* @var bool
*/
public $linkNames = 0;
/**
* Indicates if you want a preview of links inlined in the message.
*
* @var bool
*/
public $unfurlLinks;
/**
* Indicates if you want a preview of links to media inlined in the message.
*
* @var bool
*/
public $unfurlMedia;
/**
* The message's attachments.
*
* @var array
*/
public $attachments = [];
/**
* Additional request options for the Guzzle HTTP client.
*
* @var array
*/
public $http = [];
/**
* Indicate that the notification gives information about an operation.
*
* @return $this
*/
public function info()
{
$this->level = 'info';
return $this;
}
/**
* Indicate that the notification gives information about a successful operation.
*
* @return $this
*/
public function success()
{
$this->level = 'success';
return $this;
}
/**
* Indicate that the notification gives information about a warning.
*
* @return $this
*/
public function warning()
{
$this->level = 'warning';
return $this;
}
/**
* Indicate that the notification gives information about an error.
*
* @return $this
*/
public function error()
{
$this->level = 'error';
return $this;
}
/**
* Set a custom username and optional emoji icon for the Slack message.
*
* @param string $username
* @param string|null $icon
* @return $this
*/
public function from($username, $icon = null)
{
$this->username = $username;
if (! is_null($icon)) {
$this->icon = $icon;
}
return $this;
}
/**
* Set a custom image icon the message should use.
*
* @param string $image
* @return $this
*/
public function image($image)
{
$this->image = $image;
return $this;
}
/**
* Set the Slack channel the message should be sent to.
*
* @param string $channel
* @return $this
*/
public function to($channel)
{
$this->channel = $channel;
return $this;
}
/**
* Set the content of the Slack message.
*
* @param string $content
* @return $this
*/
public function content($content)
{
$this->content = $content;
return $this;
}
/**
* Define an attachment for the message.
*
* @param \Closure $callback
* @return $this
*/
public function attachment(Closure $callback)
{
$this->attachments[] = $attachment = new SlackAttachment;
$callback($attachment);
return $this;
}
/**
* Get the color for the message.
*
* @return string|null
*/
public function color()
{
switch ($this->level) {
case 'success':
return 'good';
case 'error':
return 'danger';
case 'warning':
return 'warning';
}
}
/**
* Find and link channel names and usernames.
*
* @return $this
*/
public function linkNames()
{
$this->linkNames = 1;
return $this;
}
/**
* Unfurl links to rich display.
*
* @param string $unfurl
* @return $this
*/
public function unfurlLinks($unfurl)
{
$this->unfurlLinks = $unfurl;
return $this;
}
/**
* Unfurl media to rich display.
*
* @param string $unfurl
* @return $this
*/
public function unfurlMedia($unfurl)
{
$this->unfurlMedia = $unfurl;
return $this;
}
/**
* Set additional request options for the Guzzle HTTP client.
*
* @param array $options
* @return $this
*/
public function http(array $options)
{
$this->http = $options;
return $this;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Illuminate\Notifications;
use GuzzleHttp\Client as HttpClient;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Notification;
class SlackChannelServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
Notification::resolved(function (ChannelManager $service) {
$service->extend('slack', function ($app) {
return new Channels\SlackWebhookChannel($app->make(HttpClient::class));
});
});
}
}