Skip to content
This repository has been archived by the owner on Jul 12, 2022. It is now read-only.

Commit

Permalink
Seat-Notifications (#3)
Browse files Browse the repository at this point in the history
* WIP

* WIP

* wip

* WIP

* Working Discord notifications

* WIP Slack Integration

* remove unnecessary logging.

* Starting with slack integration

* Working slack  channel

* Working Slack & Discord

* Apply fixes from StyleCI
  • Loading branch information
herpaderpaldent authored Dec 29, 2018
1 parent b301a3d commit 25d92f8
Show file tree
Hide file tree
Showing 64 changed files with 2,954 additions and 899 deletions.
24 changes: 24 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
engines:
duplication:
enabled: true
config:
languages:
- javascript
- php
fixme:
enabled: true
phpmd:
enabled: true
checks:
Controversial/CamelCaseParameterName:
enabled: false
Controversial/CamelCasePropertyName:
enabled: false
Controversial/CamelCaseVariableName:
enabled: false
ratings:
paths:
- "**.php"
exclude_paths:
- tests/
22 changes: 22 additions & 0 deletions .styleci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
preset: laravel

risky: false

enabled:
- alpha_ordered_imports
- concat_with_spaces
- no_empty_comment

disabled:
- braces
- phpdoc_no_package
- concat_without_spaces
- length_ordered_imports
- no_blank_lines_after_class_opening
- no_blank_lines_after_throw

finder:
exclude:
- "tests"
name:
- "*.php"
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
"require": {
"php": ">=7.1",
"laravel/framework": "5.5.*",
"eveseat/web": "3.0.*"
"eveseat/web": "3.0.*",
"erusev/parsedown": "^1.7",
"restcord/restcord": "^0.3",
"jolicode/slack-php-api": "^1.0"
},

"license": "GPL-2.0-only",
Expand Down
36 changes: 0 additions & 36 deletions src/Actions/Notifications/AddSeatNotification.php

This file was deleted.

25 changes: 0 additions & 25 deletions src/Actions/SeAT/AddSlackWebhook.php

This file was deleted.

97 changes: 97 additions & 0 deletions src/Caches/RedisRateLimitProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* Created by PhpStorm.
* User: Herpaderp Aldent
* Date: 25.12.2018
* Time: 16:11.
*/

namespace Herpaderpaldent\Seat\SeatNotifications\Caches;

use Illuminate\Support\Facades\Redis;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use RestCord\RateLimit\Provider\AbstractRateLimitProvider;

class RedisRateLimitProvider extends AbstractRateLimitProvider
{
/**
* @param RequestInterface $request
* @return string
*/
public function getKey(RequestInterface $request)
{
$prefix = 'seat-discord-notification';
$path = $request->getUri()->getPath();

return $prefix . ':' . strtolower($request->getMethod()) . strtr($path, ['/' => '.']);
}

/**
* Returns when the last request was made.
*
* @param RequestInterface $request
*
* @return float|null When the last request was made.
*/
public function getLastRequestTime(RequestInterface $request)
{
$key = $this->getKey($request);

return Redis::hexists($key, 'last_request') ? floatval(Redis::hget($key, 'last_request')) : 0;
}

/**
* Used to set the current time as the last request time to be queried when
* the next request is attempted.
*
* @param RequestInterface $request
*/
public function setLastRequestTime(RequestInterface $request)
{
$key = $this->getKey($request);

Redis::hset($key, 'last_request', $this->getRequestTime($request));
}

/**
* Returns the minimum amount of time that is required to have passed since
* the last request was made. This value is used to determine if the current
* request should be delayed, based on when the last request was made.
*
* Returns the allowed between the last request and the next, which
* is used to determine if a request should be delayed and by how much.
*
* @param RequestInterface $request The pending request.
*
* @return float The minimum amount of time that is required to have passed
* since the last request was made (in microseconds).
*/
public function getRequestAllowance(RequestInterface $request)
{
$key = $this->getKey($request);

return Redis::hexists($key, 'reset') ? (floatval(Redis::hget($key, 'reset')) - time()) * 1000000 : 0;
}

/**
* Used to set the minimum amount of time that is required to pass between
* this request and the next (in microseconds).
*
* @param RequestInterface $request
* @param ResponseInterface $response The resolved response.
*/
public function setRequestAllowance(RequestInterface $request, ResponseInterface $response)
{
$key = $this->getKey($request);

$remaining = $response->getHeaderLine('X-RateLimit-Remaining');
$reset = $response->getHeaderLine('X-RateLimit-Reset');

if (empty($remaining) || empty($response) || (int) $remaining > 0) {
return;
}

Redis::hset($key, 'reset', $reset);
}
}
145 changes: 145 additions & 0 deletions src/Channels/Discord/DiscordChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php
/**
* Created by PhpStorm.
* User: felix
* Date: 25.12.2018
* Time: 20:56.
*/

namespace Herpaderpaldent\Seat\SeatNotifications\Channels\Discord;

use Herpaderpaldent\Seat\SeatNotifications\Exceptions\InvalidMessage;
use Illuminate\Notifications\Notification;

class DiscordChannel
{
/**
* @var \RestCord\DiscordClient
*/
protected $discord;

public function __construct()
{
$this->discord = app('discord');
}

public function send($notifiable, Notification $notification)
{
if (! $channel = $notifiable->channel_id) {
return;
}

$message = $notification->toDiscord($notifiable);

$payload = $this->buildJSONPayload($message);

$this->discord->channel->createMessage([
'channel.id' => (int) $channel,
'content' => $payload['content'],
'embed' => $payload['embeds'][0],
]);

}

/**
* Build up a payload for the Discord Webhook.
*
* @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Discord\DiscordMessage $message
*
* @return array
*/
protected function buildPayload(DiscordMessage $message)
{
if ($this->checkMessageEmpty($message)) {
throw InvalidMessage::cannotSendAnEmptyMessage();
}
if (! is_null($message->file)) {
return $this->buildMultipartPayload($message);
}

return $this->buildJSONPayload($message);
}

/**
* Checks if the given Message is valid.
*
* @param
*
* @return bool
*/
protected function checkMessageEmpty($message)
{
if (is_null($message->content) && is_null($message->file) && is_null($message->embeds)) {
return true;
}

return false;
}

/**
* Build up a JSON payload for the Discord Webhook.
*
* @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Discord\DiscordMessage $message
*
* @return array
*/
protected function buildJSONPayload(DiscordMessage $message)
{
$optionalFields = array_filter([
'username' => data_get($message, 'username'),
'avatar_url' => data_get($message, 'avatar_url'),
'tts' => data_get($message, 'tts'),
'timestamp' => data_get($message, 'timestamp'),
]);

return array_merge([
'content' => $message->content,
'embeds' => $this->embeds($message),
], $optionalFields);
}

/**
* Build up a Multipart payload for the Discord Webhook.
*
* @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Discord\DiscordMessage $message
*
* @return array
*/
protected function buildMultipartPayload(DiscordMessage $message)
{
if (! is_null($message->embeds)) {
throw InvalidMessage::embedsNotSupportedWithFileUploads();
}
$this->type = 'multipart';

return collect($message)->forget('file')->reject(function ($value) {
return is_null($value);
})->map(function ($value, $key) {
return ['name' => $key, 'contents' => $value];
})->push($message->file)->values()->all();
}

/**
* Format the message's embedded content.
*
* @param \Herpaderpaldent\Seat\SeatNotifications\Channels\Discord\DiscordMessage $message
*
* @return array
*/
protected function embeds(DiscordMessage $message)
{
return collect($message->embeds)->map(function (DiscordEmbed $embed) {
return array_filter([
'color' => $embed->color,
'title' => $embed->title,
'description' => $embed->description,
'link' => $embed->url,
'thumbnail' => $embed->thumbnail,
'image' => $embed->image,
'footer' => $embed->footer,
'author' => $embed->author,
'fields' => $embed->fields,
]);
})->all();
}
}
Loading

0 comments on commit 25d92f8

Please sign in to comment.