From 7582e287edb5da690b0ca4a92a35fffed266be17 Mon Sep 17 00:00:00 2001 From: Roelof Roos Date: Mon, 25 Nov 2024 12:10:06 +0100 Subject: [PATCH 1/2] Removed Telegram notifications --- app/Bots/Models/Message.php | 28 ------- app/Bots/Models/Poll.php | 66 --------------- app/Bots/Models/TelegramObject.php | 69 ---------------- app/Bots/Models/Venue.php | 34 -------- app/Channels/TelegramChannel.php | 61 -------------- app/Contracts/TelegramNotification.php | 13 --- .../TelegramNotificationWithAfter.php | 13 --- .../Shop/ExpiresSoonReminder.php | 57 +------------ app/Notifications/Shop/OrderCancelled.php | 17 ---- app/Notifications/Shop/OrderExpired.php | 19 ----- app/Notifications/Shop/OrderPaid.php | 46 ----------- app/Notifications/Shop/OrderRefunded.php | 48 +---------- app/Notifications/Shop/OrderShipped.php | 17 ---- app/Notifications/Shop/RecoveredFromLimbo.php | 81 ------------------- 14 files changed, 2 insertions(+), 567 deletions(-) delete mode 100644 app/Bots/Models/Message.php delete mode 100644 app/Bots/Models/Poll.php delete mode 100644 app/Bots/Models/TelegramObject.php delete mode 100644 app/Bots/Models/Venue.php delete mode 100644 app/Channels/TelegramChannel.php delete mode 100644 app/Contracts/TelegramNotification.php delete mode 100644 app/Contracts/TelegramNotificationWithAfter.php delete mode 100644 app/Notifications/Shop/OrderPaid.php delete mode 100644 app/Notifications/Shop/RecoveredFromLimbo.php diff --git a/app/Bots/Models/Message.php b/app/Bots/Models/Message.php deleted file mode 100644 index 8af7ca753..000000000 --- a/app/Bots/Models/Message.php +++ /dev/null @@ -1,28 +0,0 @@ - $text, - ]; - } - - parent::__construct($text); - } -} diff --git a/app/Bots/Models/Poll.php b/app/Bots/Models/Poll.php deleted file mode 100644 index 2d20a0699..000000000 --- a/app/Bots/Models/Poll.php +++ /dev/null @@ -1,66 +0,0 @@ - $question, - 'options' => $options, - ]; - } - parent::__construct($question); - } - - public function addOption(string $option): self - { - $this->options = array_merge($this->options ?? [], [$option]); - - return $this; - } - - public function quiz(string $correct, ?string $explanation = null): self - { - $correct = array_search($correct, $this->options ?? [], true); - - if ($correct === false) { - throw new InvalidArgumentException('Correct option does not exist in list of options'); - } - - $this->type = 'quiz'; - $this->correct_option_id = $correct; - - if ($explanation) { - $this->explanation = $explanation; - } - - return $this; - } - - /** - * @param DateTimeInterface|int $closeDate - */ - public function closeDate($closeDate): self - { - $this->closeDate = $closeDate instanceof DateTimeInterface ? $closeDate->getTimestamp() : $closeDate; - - return $this; - } -} diff --git a/app/Bots/Models/TelegramObject.php b/app/Bots/Models/TelegramObject.php deleted file mode 100644 index b1a54929d..000000000 --- a/app/Bots/Models/TelegramObject.php +++ /dev/null @@ -1,69 +0,0 @@ -getAttributes()) - ->mapWithKeys(fn ($val, $key) => [Str::snake($key) => $val]) - ->all(); - } - - /** - * Adds a row of buttons underneath the message. - * - * @param Button[] $buttons - * @return static - */ - public function addKeyboardRow(Button ...$buttons): self - { - $this->replyMarkup ??= (new Keyboard())->inline(); - - $this->replyMarkup->row($buttons); - - return $this; - } - - /** - * Forces a reply to the bot. - * @return static - */ - public function forceReply(bool $selective = true): self - { - $this->replyMarkup = Keyboard::forceReply([ - 'selective' => $selective, - ]); - - return $this; - } -} diff --git a/app/Bots/Models/Venue.php b/app/Bots/Models/Venue.php deleted file mode 100644 index 0ae1e95f1..000000000 --- a/app/Bots/Models/Venue.php +++ /dev/null @@ -1,34 +0,0 @@ - $title, - 'address' => $address, - 'latitude' => $latitude, - 'longitude' => $longitude, - ]; - } - - parent::__construct($title); - } -} diff --git a/app/Channels/TelegramChannel.php b/app/Channels/TelegramChannel.php deleted file mode 100644 index 533f604e5..000000000 --- a/app/Channels/TelegramChannel.php +++ /dev/null @@ -1,61 +0,0 @@ -telegram_id) { - return; - } - - // Allow message to construct - $message = $notification->toTelegramMessage($notifiable); - - // Enforce some rules - $message->chatId($notifiable->telegram_id); - $message->disableWebPagePreview(true); - - // Get the bot out - $bot = Telegram::bot(); - - // Determine proper action - $method = 'send' . class_basename($message); - if (! method_exists($bot, $method)) { - $method = 'sendMessage'; - } - - // Send and check result - try { - $result = $bot->{$method}($message->toArray()); - } catch (TelegramResponseException $exception) { - Log::warning('Failed to send message to Telegram: {exception}', [ - 'exception' => $exception, - 'message' => $message->toArray(), - ]); - - return; - } - - // Allow an after hook - if ($notification instanceof TelegramNotificationWithAfter) { - $notification->afterTelegramMessage($result, $notifiable); - } - } -} diff --git a/app/Contracts/TelegramNotification.php b/app/Contracts/TelegramNotification.php deleted file mode 100644 index 26b318c8f..000000000 --- a/app/Contracts/TelegramNotification.php +++ /dev/null @@ -1,13 +0,0 @@ -subject('Je webwinkel bestelling verloopt bijna!') ->greeting("Beste {$notifiable->first_name},") - ->line("Op {$orderDate} om {$orderTime} heb je een bestelling geplaatst in de Gumbo webwinkel ter waarde van {$value}.") ->line("Deze bestelling moet je betaald hebben voor {$expiration}, anders annuleren we deze.") - ->action('Nu betalen', url('/')) - ->line('Als je geen behoefte hebt om deze bestelling af te ronden, dan hoef je niks te doen.') - ->salutation('Tot snel!'); } - - /** - * Get the Telegram message to send. - */ - public function toTelegramMessage(User $notifiable): TelegramObject - { - $order = $this->order; - $expiresIn = Date::now()->diffForHumans($order->expires_at, CarbonInterface::DIFF_ABSOLUTE); - $value = Str::price($this->order->price); - - $message = <<number} af te ronden! - TEXT; - - return Message::make($message) - ->addKeyboardRow( - Keyboard::inlineButton([ - 'text' => "Nu {$value} betalen", - 'url' => route('shop.order.pay', $this->order), - ]), - ) - ->addKeyboardRow( - Keyboard::inlineButton([ - 'text' => 'Bestelling annuleren', - 'url' => route('shop.order.cancel', $this->order), - ]), - ); - } } diff --git a/app/Notifications/Shop/OrderCancelled.php b/app/Notifications/Shop/OrderCancelled.php index 987462c00..b6c738986 100644 --- a/app/Notifications/Shop/OrderCancelled.php +++ b/app/Notifications/Shop/OrderCancelled.php @@ -8,18 +8,6 @@ class OrderCancelled extends ShopNotification { - /** - * Get the notification's delivery channels. - * - * @return array - */ - public function via($notifiable) - { - return [ - 'mail', - ]; - } - /** * Get the mail representation of the notification. * @@ -32,18 +20,13 @@ public function toMail($notifiable) return (new MailMessage()) ->subject("Bestelling {$order->number} geannuleerd") - ->greeting("Beste {$notifiable->first_name},") - ->line("Je bestelling van {$date} (bestelnummer {$order->number}) is geannuleerd.") - ->line('Als je toch de producten wil kopen, kan je hieronder de bestelling bekijken ter referentie.') - ->action( 'Bekijk bestelling', route('shop.order.show', $order), ) - ->salutation('Tot snel!'); } } diff --git a/app/Notifications/Shop/OrderExpired.php b/app/Notifications/Shop/OrderExpired.php index c86719b83..ecdfdd276 100644 --- a/app/Notifications/Shop/OrderExpired.php +++ b/app/Notifications/Shop/OrderExpired.php @@ -8,18 +8,6 @@ class OrderExpired extends ShopNotification { - /** - * Get the notification's delivery channels. - * - * @return array - */ - public function via($notifiable) - { - return [ - 'mail', - ]; - } - /** * Get the mail representation of the notification. * @@ -32,22 +20,15 @@ public function toMail($notifiable) return (new MailMessage()) ->subject("Bestelling {$order->number} verlopen") - ->greeting("Beste {$notifiable->first_name},") - ->line("Je hebt op {$date} een bestelling geplaatst (nummertje {$order->number}), maar deze niet op tijd betaald.") - ->line('Omdat je met jouw bestelling ook een stukje voorraad dibst, moet je op tijd betalen.') - ->line("**BUT YOU DIDN'T, DID YOU NOW!?**") - ->line('Dus, om deze reden is jouw bestelling het raam uit gegooit. Als je toch de producten wil kopen, mag je opnieuw naar de webshop.') - ->action( 'Bekijk bestelling', route('shop.order.show', $order), ) - ->salutation('Tot snel!'); } } diff --git a/app/Notifications/Shop/OrderPaid.php b/app/Notifications/Shop/OrderPaid.php deleted file mode 100644 index c3394fed0..000000000 --- a/app/Notifications/Shop/OrderPaid.php +++ /dev/null @@ -1,46 +0,0 @@ -order; - - $message = <<number} is betaald** - - Het bestuur neemt contact met je op over de levering. - TEXT; - - return Message::make($message) - ->addKeyboardRow( - Keyboard::inlineButton([ - 'text' => 'Bekijk bestelling', - 'url' => route('shop.order.show', $this->order), - ]), - ); - } -} diff --git a/app/Notifications/Shop/OrderRefunded.php b/app/Notifications/Shop/OrderRefunded.php index cde0dec3c..c17a9bbe0 100644 --- a/app/Notifications/Shop/OrderRefunded.php +++ b/app/Notifications/Shop/OrderRefunded.php @@ -4,17 +4,11 @@ namespace App\Notifications\Shop; -use App\Bots\Models\Message; -use App\Bots\Models\TelegramObject; -use App\Channels\TelegramChannel; -use App\Contracts\TelegramNotification; use App\Helpers\Str; use App\Models\Shop\Order; -use App\Models\User; use Illuminate\Notifications\Messages\MailMessage; -use Telegram\Bot\Keyboard\Keyboard; -class OrderRefunded extends ShopNotification implements TelegramNotification +class OrderRefunded extends ShopNotification { protected int $amount; @@ -33,19 +27,6 @@ public function __construct(Order $order, int $amount, string $account) $this->account = $account; } - /** - * Get the notification's delivery channels. - * - * @return array - */ - public function via($notifiable) - { - return [ - 'mail', - TelegramChannel::class, - ]; - } - /** * Get the mail representation of the notification. * @@ -58,40 +39,13 @@ public function toMail($notifiable) return (new MailMessage()) ->subject("Terugbetaling voor bestelling {$order->number} verzonden") - ->greeting("Beste {$notifiable->first_name},") - ->line("Er is een terugbetaling verstuurd naar Mollie voor bestelling {$order->number}.") ->line("Binnen enkele dagen krijg je het bedrag van {$amount} teruggestort op je bankrekening eindigend op {$this->account}.") - ->action( 'Bekijk bestelling', route('shop.order.show', $order), ) - ->salutation('Tot snel!'); } - - /** - * Get the Telegram message to send. - */ - public function toTelegramMessage(User $notifiable): TelegramObject - { - $order = $this->order; - $amount = Str::price($this->amount); - - $message = <<number}. - TEXT; - - return Message::make($message) - ->addKeyboardRow( - Keyboard::inlineButton([ - 'text' => 'Bekijk bestelling', - 'url' => route('shop.order.show', $this->order), - ]), - ); - } } diff --git a/app/Notifications/Shop/OrderShipped.php b/app/Notifications/Shop/OrderShipped.php index 3511e9216..7f8ac1017 100644 --- a/app/Notifications/Shop/OrderShipped.php +++ b/app/Notifications/Shop/OrderShipped.php @@ -8,18 +8,6 @@ class OrderShipped extends ShopNotification { - /** - * Get the notification's delivery channels. - * - * @return array - */ - public function via($notifiable) - { - return [ - 'mail', - ]; - } - /** * Get the mail representation of the notification. * @@ -32,18 +20,13 @@ public function toMail($notifiable) return (new MailMessage()) ->subject("Bestelling {$order->number} afgerond") - ->greeting("Beste {$notifiable->first_name},") - ->line("Bij deze even een bevestiging dat je bestelling van {$date} (bestelnummer {$order->number}) is afgerond.") - ->line('Mochten er nog problemen zijn met je aankoop, neem dan contact op met het bestuur.') - ->action( 'Bekijk bestelling', route('shop.order.show', $order), ) - ->salutation('Tot snel!'); } } diff --git a/app/Notifications/Shop/RecoveredFromLimbo.php b/app/Notifications/Shop/RecoveredFromLimbo.php deleted file mode 100644 index 94e6d5918..000000000 --- a/app/Notifications/Shop/RecoveredFromLimbo.php +++ /dev/null @@ -1,81 +0,0 @@ -order->created_at->isoFormat('dddd D MMMM'); - - return (new MailMessage()) - ->subject('je kunt nu betalen!') - - ->greeting("Beste {$notifiable->first_name},") - - ->line('Sorry dat er wat fout ging bij je bestelling, waardoor je niet verder kon.') - ->line("We hebben je bestelling van {$orderDate} opgeduikeld uit limbo en je kan hem nu betalen.") - - ->action('Bekijk bestelling', route('shop.order.show', $this->order)) - - ->line('Als je geen behoefte meer hebt om deze bestelling af te ronden, dan hoef je niks te doen.') - - ->salutation('Tot snel!'); - } - - /** - * Get the Telegram message to send. - */ - public function toTelegramMessage(User $notifiable): TelegramObject - { - $order = $this->order; - $expiresIn = Date::now()->diffForHumans($order->expires_at, CarbonInterface::DIFF_ABSOLUTE); - $value = Str::price($this->order->price); - - $message = <<addKeyboardRow( - Keyboard::inlineButton([ - 'text' => 'Bekijk bestelling', - 'url' => route('shop.order.show', $this->order), - ]), - ); - } -} From 5b80cbf7dd7c23df57980babf5a3de327e3d043e Mon Sep 17 00:00:00 2001 From: Roelof Roos Date: Mon, 25 Nov 2024 12:12:15 +0100 Subject: [PATCH 2/2] Removed some commands --- app/Bots/Commands/BeerCommand.php | 161 ------------------ app/Bots/Commands/CoffeeConditionCommand.php | 75 --------- app/Bots/Commands/LeaderboardCommand.php | 95 ----------- app/Bots/Commands/WebcamCommand.php | 166 ------------------- app/Bots/Services/CoffeeConditionService.php | 116 ------------- config/telegram.php | 4 - 6 files changed, 617 deletions(-) delete mode 100644 app/Bots/Commands/BeerCommand.php delete mode 100644 app/Bots/Commands/CoffeeConditionCommand.php delete mode 100644 app/Bots/Commands/LeaderboardCommand.php delete mode 100644 app/Bots/Commands/WebcamCommand.php delete mode 100644 app/Bots/Services/CoffeeConditionService.php diff --git a/app/Bots/Commands/BeerCommand.php b/app/Bots/Commands/BeerCommand.php deleted file mode 100644 index 6d3ca2df0..000000000 --- a/app/Bots/Commands/BeerCommand.php +++ /dev/null @@ -1,161 +0,0 @@ - - */ - protected array $aliases = ['beer']; - - /** - * Handle the activity. - */ - public function handle() - { - // Get TG user - $tgUser = $this->getTelegramUser(); - - // Get user and check member rights - $user = $this->getUser(); - if (! $this->ensureIsMember($user)) { - return; - } - - // Check the rate limit - $rateLimitKey = "tg.beer:{$tgUser->id}"; - $remaining = RateLimiter::remaining($rateLimitKey, self::RATE_LIMIT_ALL); - - Log::info('Beer command called by telegram user {user} with {remaining} hits remaining.', [ - 'user' => $tgUser->id, - 'remaining' => $remaining, - ]); - - if ($remaining <= 0) { - $this->replyWithMessage([ - 'text' => '⏸ Rate limited', - ]); - - return; - } - - // Smash that rate limiter - RateLimiter::hit( - key: $rateLimitKey, - decaySeconds: 60 * 30, // Decays in 30 minutes - ); - - if ($remaining > (self::RATE_LIMIT_ALL - self::RATE_LIMIT_BEER)) { - $this->replyWithMessage([ - 'text' => "🍻 {$this->buildBeerResponse()}", - ]); - - return; - } - - $this->replyWithMessage([ - 'text' => "🥤 {$this->buildAlternativeResponse()}", - ]); - } - - /** - * Load and parse Yaml file, cache for an hour. - */ - private function loadConfigFile(string $file): array - { - $path = resource_path(sprintf(self::BEER_CONFIG_TEMPLATE, $file)); - if (! file_exists($path) || ! is_file($path)) { - throw new RuntimeException('Invalid config file'); - } - - $cacheKey = "beer.file.{$file}"; - - return Cache::remember($cacheKey, Date::now()->addHour(), fn () => Yaml::parseFile($path)); - } - - private function buildBeerResponse(): string - { - // Get intended file - $configFile = self::BEER_CONFIG_DEFAULT; - $nowDate = Date::now()->startOfDay(); - foreach (self::BEER_CONFIG_VARIANTS as [$start, $end, $file]) { - $startDate = Date::createFromFormat('d-m', $start)->startOfDay(); - $endDate = Date::createFromFormat('d-m', $end)->startOfDay(); - - if ($startDate <= $nowDate && $endDate >= $nowDate) { - $configFile = $file; - - break; - } - } - - // Get file from cache, or disk if missing - $config = $this->loadConfigFile($configFile); - - // Get random lines - return sprintf( - self::BEER_LINE, - Arr::random($config['targets']), - Arr::random($config['methods']), - Arr::random($config['adjectives']), - Arr::random($config['subjects']), - ); - } - - private function buildAlternativeResponse(): string - { - // Get file from cache, or disk if missing - $config = $this->loadConfigFile(self::BEER_ALTERNATIVES); - - // Format string - return sprintf( - self::BEER_ALTERNATIVES_LINE, - Arr::random($config['rejects']), - Arr::random($config['alternatives']), - ); - } -} diff --git a/app/Bots/Commands/CoffeeConditionCommand.php b/app/Bots/Commands/CoffeeConditionCommand.php deleted file mode 100644 index bcf975371..000000000 --- a/app/Bots/Commands/CoffeeConditionCommand.php +++ /dev/null @@ -1,75 +0,0 @@ - true, - 'gezet' => true, - 'fresh' => true, - 'brew' => true, - 'weg' => false, - 'op' => false, - 'gone' => false, - 'out' => false, - ]; - - /** - * The name of the Telegram command. - */ - protected string $name = 'koffie'; - - /** - * The Telegram command description. - */ - protected string $description = 'Meld of bekijk de koffie conditie.'; - - /** - * Handle the activity. - */ - public function handle() - { - // Fetch user - $user = $this->getUser(); - if (! $this->ensureIsMember($user)) { - return; - } - - /** @var CoffeeConditionService $service */ - $service = App::make(CoffeeConditionService::class); - - // Check message - $secondWordInMessage = (string) Str::of($this->getCommandBody())->words(1, '')->trim()->lower(); - if (empty($secondWordInMessage)) { - $condition = $service->getCoffeeCondition(); - - $this->replyWithMessage(['text' => $condition]); - - return; - } - - if (! array_key_exists($secondWordInMessage, self::VALID_COFFEE_STRINGS)) { - $this->replyWithMessage(['text' => __('Invalid coffee condition, please use one of the following: :conditions', [ - 'conditions' => 'gezet, op', - ])]); - - return; - } - - $this->replyWithMessage([ - 'text' => $service->setCoffee($user, self::VALID_COFFEE_STRINGS[$secondWordInMessage]), - ]); - } -} diff --git a/app/Bots/Commands/LeaderboardCommand.php b/app/Bots/Commands/LeaderboardCommand.php deleted file mode 100644 index b62b2656b..000000000 --- a/app/Bots/Commands/LeaderboardCommand.php +++ /dev/null @@ -1,95 +0,0 @@ -replyWithChatAction(['action' => Actions::TYPING]); - - // Members only - $user = $this->getUser(); - if (! $this->ensureIsMember($user)) { - return; - } - - // Compute top 10 - $referrals = MemberReferral::query() - ->select( - 'user_id', - DB::raw('COUNT(*) as referral_count'), - ) - ->groupBy('user_id') - ->orderByDesc('referral_count') - ->with('user') - ->has('user') - ->take(5) - ->get(); - - if ($referrals->isEmpty()) { - $this->replyWithMessage([ - 'text' => self::MESSAGE_EMPTY, - ]); - - return; - } - - $ranks = []; - foreach ($referrals as $offset => $referral) { - assert($referral instanceof MemberReferral); - - $emojiOrListItem = self::EMOJI[$offset] ?? '-'; - $body = trans_choice(':user with :count member|:user with :count members', $referral->referral_count, [ - 'user' => e($referral->user->leaderboard_name), - ]); - - $ranks[] = "{$emojiOrListItem} {$body}"; - } - - // Return message - $this->replyWithMessage([ - 'text' => sprintf(self::MESSAGE_TEMPLATE, implode(PHP_EOL, $ranks)), - ]); - } -} diff --git a/app/Bots/Commands/WebcamCommand.php b/app/Bots/Commands/WebcamCommand.php deleted file mode 100644 index 66c9f9fd5..000000000 --- a/app/Bots/Commands/WebcamCommand.php +++ /dev/null @@ -1,166 +0,0 @@ -getCameras() - ->where('slug', '!=', $this->getName()); - - return Collection::make() - ->merge($cameras->pluck('slug')) - ->merge($cameras->pluck('command')) - ->map(fn ($value) => Str::slug($value)) - ->reject(fn ($value) => $value === $this->getName() || ! Str::endsWith($value, 'cam')) - ->unique() - ->toArray(); - } - - public function getDescriptionFor(string $command): string - { - $targetCamera = $this->getCameras() - ->filter(fn ($row) => Str::slug($row->command) === $command || Str::slug($row->slug) === $command) - ->first(); - - return $targetCamera ? "Toont de {$targetCamera->name}" : $this->description; - } - - /** - * Handle the activity. - */ - public function handle() - { - // Get user - $user = $this->getUser(); - - // Reject if rate-limited - if (! $user) { - $this->replyWithMessage(['text' => self::REPLY_GUEST]); - - return; - } - - // Get image - $requested = Str::slug($this->getCommandName() ?? $this->getName()); - $webcam = Camera::query() - ->where(function (Builder $query) use ($requested) { - $query - ->where('slug', $requested) - ->orWhere('command', $requested); - }) - ->first(); - - if (! $webcam) { - $this->replyWithMessage([ - 'text' => $this->formatText(self::REPLY_NO_SUCH_CAMERA, e(strip_tags($requested))), - ]); - - return; - } - - // Check if expired - if ($webcam->is_expired || $webcam->device?->path === null) { - $this->replyWithMessage([ - 'text' => $this->formatText(self::REPLY_NOT_AVAILABLE, $webcam->name), - ]); - - return; - } - - $device = $webcam->device; - $disk = Storage::disk(Config::get('gumbo.images.disk')); - - // Send upload status - $this->replyWithChatAction(['action' => Actions::UPLOAD_PHOTO]); - - // Check if image exists - if ($disk->missing($device->path)) { - $this->replyWithMessage([ - 'text' => $this->formatText(self::REPLY_FILE_LOST), - ]); - - report(new RuntimeException( - "Failed to retrieve photo file [{$device->path}] for webcam [{$webcam->id}] (device [{$device->id}]!", - )); - - return; - } - - // Prep file - $file = new InputFile( - $disk->readStream($device->path), - (string) Str::of("{$webcam->slug}.jpg")->ascii()->lower(), - ); - - // Return message - $this->replyWithPhoto([ - 'photo' => $file, - 'caption' => sprintf('%s van %s', $webcam->name, $device->updated_at->isoFormat('ddd D MMM YYYY, HH:mm (z)')), - ]); - } - - protected function getCameras(): Collection - { - return $this->cams ??= Camera::all(); - } -} diff --git a/app/Bots/Services/CoffeeConditionService.php b/app/Bots/Services/CoffeeConditionService.php deleted file mode 100644 index 767d70265..000000000 --- a/app/Bots/Services/CoffeeConditionService.php +++ /dev/null @@ -1,116 +0,0 @@ - 'fresh', - 'PT1H' => 'okay', - 'PT2H' => 'stale', - 'PT4H' => 'old', - 'PT8H' => 'yeasty', - ]; - - /** - * Builds a report on the coffee condition, returning the chat message to send. - */ - public function getCoffeeCondition(): string - { - $status = $this->readCoffeeStatus(); - if ($status === null) { - return __('The coffee condition is unknown.'); - } - - /** @var Carbon $date */ - $date = $status->date; - if ($date->dayOfYear() != Date::now()->dayOfYear()) { - return __('The coffee condition is unknown.'); - } - - // If it's gone, it's gone - if (! $status->coffee) { - return implode(PHP_EOL, [ - __('There is no more coffee.'), - __('The state was last updated by :user :ago.', [ - 'user' => $status->user?->first_name, - 'ago' => $date->diffForHumans(), - ]), - ]); - } - - $condition = 'very fresh'; - foreach (self::COFFEE_FRESHNESS as $interval => $freshness) { - if (Date::now()->sub($interval)->isAfter($date)) { - $condition = $freshness; - } - } - - return implode(PHP_EOL, [ - __('The coffee is :condition.', ['condition' => __($condition)]), - __('The coffee was brewed by :user :ago.', [ - 'user' => $status->user->first_name, - 'ago' => $date->diffForHumans(), - ]), - ]); - } - - /** - * Changes the coffee condition. - */ - public function setCoffee(User $user, bool $coffee): string - { - $this->writeCoffeeStatus($user, $coffee); - - return __($coffee ? 'Thank you for brewing coffee :name!' : 'Thank you for letting us know there is no more coffee :name!', [ - 'name' => $user->first_name, - ]); - } - - /** - * Returns coffee status, if any. - */ - private function readCoffeeStatus(): ?object - { - if (! Storage::exists(self::COFFEE_FILE)) { - return null; - } - - $raw = Storage::get(self::COFFEE_FILE); - $data = json_decode($raw, true, 4, JSON_THROW_ON_ERROR); - - $data = array_merge([ - 'coffee' => null, - 'user' => null, - 'date' => null, - ], json_decode($raw, true, 4, JSON_THROW_ON_ERROR)); - - $data['user'] = User::find($data['user'] ?? -1); - $data['date'] = Date::parse($data['date'] ?? 'now'); - - return (object) $data; - } - - /** - * Writes the coffee status. - * @throws InvalidArgumentException - */ - private function writeCoffeeStatus(User $user, bool $isCoffee): void - { - Storage::put(self::COFFEE_FILE, json_encode([ - 'coffee' => $isCoffee, - 'user' => $user->id, - 'date' => Date::now(), - ])); - } -} diff --git a/config/telegram.php b/config/telegram.php index fbee156f8..26cd0e8c2 100644 --- a/config/telegram.php +++ b/config/telegram.php @@ -40,15 +40,11 @@ 'webhook_url' => env('TELEGRAM_WEBHOOK_URL', 'api/bots/telegram'), 'commands' => [ App\Bots\Commands\ActivitiesCommand::class, - App\Bots\Commands\BeerCommand::class, - App\Bots\Commands\LeaderboardCommand::class, App\Bots\Commands\LoginCommand::class, App\Bots\Commands\LogoutCommand::class, App\Bots\Commands\QuoteCommand::class, App\Bots\Commands\SackCommand::class, - App\Bots\Commands\WebcamCommand::class, App\Bots\Commands\StartCommand::class, - App\Bots\Commands\CoffeeConditionCommand::class, ], ], ],