#116 - integration with slack (#129)

* wip

* wip

* wip

* wip

* fix

* wip

* wip

* fix

* fix

* cs fix

* #116 - fix

* #116 - changed home-office icon

* Apply suggestions from code review

Co-authored-by: Krzysztof Rewak <krzysztof.rewak@gmail.com>

* #116 - cr fix

* #116 - cs fix

* #116 - cs fix

* Apply suggestions from code review

Co-authored-by: Ewelina Lasowy <56546832+EwelinaLasowy@users.noreply.github.com>

* #5 - bump codestyle

Co-authored-by: EwelinaLasowy <ewelina.lasowy@blumilk.pl>
Co-authored-by: Krzysztof Rewak <krzysztof.rewak@gmail.com>
Co-authored-by: Ewelina Lasowy <56546832+EwelinaLasowy@users.noreply.github.com>
This commit is contained in:
Adrian Hopek
2022-04-27 09:57:13 +02:00
committed by GitHub
parent d60dc75f99
commit c69866bb52
78 changed files with 1597 additions and 243 deletions

View File

@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Spatie\SlashCommand\Handlers\BaseHandler;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Infrastructure\Slack\Elements\Attachment;
use Toby\Infrastructure\Slack\Traits\ListsHandlers;
class CatchAll extends BaseHandler
{
use ListsHandlers;
public function canHandle(Request $request): bool
{
return true;
}
public function handle(Request $request): Response
{
$handlers = $this->findAvailableHandlers();
$attachmentFields = $this->mapHandlersToAttachments($handlers);
return $this->respondToSlack(":x: Nie rozpoznaję polecenia. Lista wszystkich poleceń:")
->withAttachment(
Attachment::create()
->setColor("danger")
->useMarkdown()
->setFields($attachmentFields),
);
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Domain\DailySummaryRetriever;
use Toby\Infrastructure\Slack\Elements\AbsencesAttachment;
use Toby\Infrastructure\Slack\Elements\BirthdaysAttachment;
use Toby\Infrastructure\Slack\Elements\RemotesAttachment;
class DailySummary extends SignatureHandler
{
protected $signature = "toby dzisiaj";
protected $description = "Codzienne podsumowanie";
public function handle(Request $request): Response
{
$dailySummaryRetriever = app()->make(DailySummaryRetriever::class);
$now = Carbon::today();
$attachments = new Collection([
new AbsencesAttachment($dailySummaryRetriever->getAbsences($now)),
new RemotesAttachment($dailySummaryRetriever->getRemoteDays($now)),
new BirthdaysAttachment($dailySummaryRetriever->getBirthdays($now)),
]);
return $this->respondToSlack("Podsumowanie dla dnia {$now->toDisplayString()}")
->withAttachments($attachments->all());
}
}

View File

@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Illuminate\Validation\ValidationException;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Domain\Notifications\KeyHasBeenGivenNotification;
use Toby\Eloquent\Models\Key;
use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException;
use Toby\Infrastructure\Slack\Rules\SlackUserExistsRule;
use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId;
class GiveKeysTo extends SignatureHandler
{
use FindsUserBySlackId;
protected $signature = "toby klucze:dla {user}";
protected $description = "Przekaż klucze wskazanemu użytkownikowi";
/**
* @throws UserNotFoundException
* @throws ValidationException
*/
public function handle(Request $request): Response
{
["user" => $from] = $this->validate();
$authUser = $this->findUserBySlackIdOrFail($request->userId);
$user = $this->findUserBySlackId($from);
/** @var Key $key */
$key = $authUser->keys()->first();
if (!$key) {
throw ValidationException::withMessages(["key" => "Nie masz żadnego klucza do przekazania"]);
}
if ($user->is($authUser)) {
throw ValidationException::withMessages([
"key" => "Nie możesz przekazać sobie kluczy :dzban:",
]);
}
$key->user()->associate($user);
$key->save();
$key->notify(new KeyHasBeenGivenNotification($authUser, $user));
return $this->respondToSlack(
":white_check_mark: Klucz nr {$key->id} został przekazany użytkownikowi <@{$user->profile->slack_id}>",
);
}
protected function getRules(): array
{
return [
"user" => ["required", new SlackUserExistsRule()],
];
}
protected function getMessages(): array
{
return [
"user.required" => "Musisz podać użytkownika, któremu chcesz przekazać klucze",
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Infrastructure\Slack\Elements\Attachment;
use Toby\Infrastructure\Slack\Traits\ListsHandlers;
class Help extends SignatureHandler
{
use ListsHandlers;
protected $signature = "toby pomoc";
protected $description = "Wyświetl wszystkie dostępne polecenia";
public function handle(Request $request): Response
{
$handlers = $this->findAvailableHandlers();
$attachmentFields = $this->mapHandlersToAttachments($handlers);
return $this->respondToSlack("Dostępne polecenia:")
->withAttachment(
Attachment::create()
->setColor("good")
->useMarkdown()
->setFields($attachmentFields),
);
}
}

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Illuminate\Support\Carbon;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Domain\Actions\VacationRequest\CreateAction;
use Toby\Domain\Enums\VacationType;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\YearPeriod;
use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId;
class HomeOffice extends SignatureHandler
{
use FindsUserBySlackId;
protected $signature = "toby zdalnie";
protected $description = "Pracuj dzisiaj zdalnie";
public function handle(Request $request): Response
{
$user = $this->findUserBySlackId($request->userId);
$this->createRemoteday($user, Carbon::today());
return $this->respondToSlack(":white_check_mark: Pracujesz dzisiaj zdalnie");
}
protected function createRemoteday(User $user, Carbon $date): void
{
$yearPeriod = YearPeriod::findByYear($date->year);
app(CreateAction::class)->execute([
"user_id" => $user->id,
"type" => VacationType::HomeOffice,
"from" => $date,
"to" => $date,
"year_period_id" => $yearPeriod->id,
"flow_skipped" => false,
], $user);
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Eloquent\Models\Key;
use Toby\Infrastructure\Slack\Elements\KeysAttachment;
class KeyList extends SignatureHandler
{
protected $signature = "toby klucze";
protected $description = "Lista wszystkich kluczy";
public function handle(Request $request): Response
{
$keys = Key::query()
->orderBy("id")
->get();
return $this->respondToSlack("Lista kluczy :key:")
->withAttachment(new KeysAttachment($keys));
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Illuminate\Support\Facades\Validator;
use Spatie\SlashCommand\Handlers\SignatureHandler as BaseSignatureHandler;
abstract class SignatureHandler extends BaseSignatureHandler
{
public function validate()
{
return Validator::validate($this->getArguments(), $this->getRules(), $this->getMessages());
}
protected function getRules(): array
{
return [];
}
protected function getMessages(): array
{
return [];
}
}

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace Toby\Infrastructure\Slack\Handlers;
use Illuminate\Validation\ValidationException;
use Spatie\SlashCommand\Request;
use Spatie\SlashCommand\Response;
use Toby\Domain\Notifications\KeyHasBeenTakenNotification;
use Toby\Eloquent\Models\Key;
use Toby\Infrastructure\Slack\Exceptions\UserNotFoundException;
use Toby\Infrastructure\Slack\Rules\SlackUserExistsRule;
use Toby\Infrastructure\Slack\Traits\FindsUserBySlackId;
class TakeKeysFrom extends SignatureHandler
{
use FindsUserBySlackId;
protected $signature = "toby klucze:od {user}";
protected $description = "Zabierz klucze wskazanemu użytkownikowi";
/**
* @throws UserNotFoundException|ValidationException
*/
public function handle(Request $request): Response
{
["user" => $from] = $this->validate();
$authUser = $this->findUserBySlackIdOrFail($request->userId);
$user = $this->findUserBySlackId($from);
/** @var Key $key */
$key = $user->keys()->first();
if (!$key) {
throw ValidationException::withMessages([
"key" => "Użytkownik <@{$user->profile->slack_id}> nie ma żadnych kluczy",
]);
}
if ($key->user()->is($authUser)) {
throw ValidationException::withMessages([
"key" => "Nie możesz zabrać sobie kluczy :dzban:",
]);
}
$key->user()->associate($authUser);
$key->save();
$key->notify(new KeyHasBeenTakenNotification($authUser, $user));
return $this->respondToSlack(":white_check_mark: Klucz nr {$key->id} został zabrany użytkownikowi <@{$user->profile->slack_id}>");
}
protected function getRules(): array
{
return [
"user" => ["required", new SlackUserExistsRule()],
];
}
protected function getMessages(): array
{
return [
"user.required" => "Musisz podać użytkownika, któremu chcesz zabrać klucze",
];
}
}