]> git.localhorst.tv Git - alttp.git/commitdiff
discord app events show command
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 31 Jul 2025 09:33:27 +0000 (11:33 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 31 Jul 2025 09:33:27 +0000 (11:33 +0200)
app/Console/Commands/DiscordBotCommand.php
app/DiscordAppCommands/AlttpCommand.php
app/DiscordAppCommands/AlttpTechCommand.php
app/DiscordAppCommands/EventsCommand.php [new file with mode: 0644]
app/DiscordAppCommands/EventsShowCommand.php [new file with mode: 0644]
app/Models/DiscordGuild.php
app/Models/Event.php

index 769f284ca8cd6e3a9c66a10438d3eba6db32d82b..26e7f9147f8e201e01832d989876759ed5a88cfb 100644 (file)
@@ -3,13 +3,13 @@
 namespace App\Console\Commands;
 
 use App\DiscordAppCommands\AlttpCommand;
+use App\DiscordAppCommands\EventsCommand;
 use App\Models\DiscordBotCommand as CommandModel;
 use App\Models\DiscordChannel;
 use App\Models\DiscordGuild;
 use App\Models\DiscordRole;
 use Discord\Discord;
 use Discord\Parts\Channel\Channel;
-use Discord\Parts\Channel\Message;
 use Discord\Parts\Guild\Guild;
 use Discord\Parts\Guild\Role;
 use Discord\Parts\User\Activity;
@@ -17,8 +17,8 @@ use Discord\WebSockets\Event;
 use Discord\WebSockets\Intents;
 use Illuminate\Console\Command;
 use Monolog\Handler\StreamHandler;
+use Monolog\Level;
 use Monolog\Logger;
-use React\EventLoop\Loop;
 
 class DiscordBotCommand extends Command
 {
@@ -44,7 +44,7 @@ class DiscordBotCommand extends Command
        public function handle()
        {
                $logger = new Logger('DiscordBot');
-               $logger->pushHandler(new StreamHandler('php://stdout', Logger::INFO));
+               $logger->pushHandler(new StreamHandler('php://stdout', Level::Info));
                $discord = new Discord([
                        'intents' => Intents::getDefaultIntents() | Intents::GUILD_MEMBERS,
                        'logger' => $logger,
@@ -58,7 +58,7 @@ class DiscordBotCommand extends Command
                        $discord->updatePresence($activity);
 
                        $discord->getLoop()->addPeriodicTimer(1, function () use ($discord) {
-                               $command = CommandModel::where('status', '=', 'pending')->oldest()->first();
+                               $command = CommandModel::query()->where('status', '=', 'pending')->oldest()->first();
                                if ($command) {
                                        $this->line('executing command '.$command->id.': '.$command->command);
                                        try {
@@ -70,9 +70,11 @@ class DiscordBotCommand extends Command
 
                        if (config('discord.enable_commands')) {
                                AlttpCommand::listen($discord);
+                               EventsCommand::listen($discord);
                        }
                        if (config('discord.create_commands')) {
                                AlttpCommand::create($discord);
+                               EventsCommand::create($discord);
                        }
                });
                $discord->on(Event::GUILD_CREATE, function (Guild $guild, Discord $discord) {
@@ -131,7 +133,7 @@ class DiscordBotCommand extends Command
                                $this->error('guild role delete: '.$e->getMessage());
                        }
                });
-               $discord->getLoop()->addSignal(SIGINT, function() use ($discord) {
+               $discord->getLoop()->addSignal(SIGINT, function () use ($discord) {
                        $discord->close();
                });
                $discord->run();
index e27767b08702da53c2af95bda7a10333c971f154..c7d782e064c22d3bebfa1808948b14b11dd02fa5 100644 (file)
@@ -7,7 +7,7 @@ use Discord\Discord;
 
 class AlttpCommand {
 
-       public static function create(Discord $discord) {
+       public static function create(Discord $discord): void {
                $command = CommandBuilder::new();
                $command->setName('alttp');
                $command->setDescription('A Link to the Past');
@@ -17,7 +17,7 @@ class AlttpCommand {
                );
        }
 
-       public static function listen(Discord $discord) {
+       public static function listen(Discord $discord): void {
                AlttpTechCommand::listen('alttp', $discord);
        }
 
index ac341ba46b22282d7b3b53e9dd9b5ea71f5944ca..1cd9b20c7aa0bf73bf75810bec7ad191adaf6a7e 100644 (file)
@@ -6,13 +6,12 @@ use App\Models\Technique;
 use Discord\Builders\MessageBuilder;
 use Discord\Discord;
 use Discord\Parts\Embed\Embed;
-use Discord\Parts\Embed\Footer;
 use Discord\Parts\Interactions\Command\Option;
 use Discord\Parts\Interactions\Interaction;
 
 class AlttpTechCommand {
 
-       public static function create(Discord $discord) {
+       public static function create(Discord $discord): Option {
                $command = new Option($discord);
                $command->setType(Option::SUB_COMMAND);
                $command->setName('tech');
@@ -27,17 +26,17 @@ class AlttpTechCommand {
                return $command;
        }
 
-       public static function listen($parent, Discord $discord) {
+       public static function listen(string $parent, Discord $discord): void {
                $discord->listenCommand(
                        [$parent, 'tech'],
                        function (Interaction $interaction) use ($discord) {
                                $interaction
                                        ->acknowledgeWithResponse()
-                                       ->done(function() use ($discord, $interaction) {
+                                       ->done(function () use ($discord, $interaction) {
                                                try {
                                                        $lang = Technique::locale2lang($interaction->locale);
-                                                       $tech = Technique
-                                                               ::where('type', '=', 'tech')
+                                                       $tech = Technique::query()
+                                                               ->where('type', '=', 'tech')
                                                                ->where('name', '=', $interaction->data->options['tech']->options['name']->value)
                                                                ->firstOrFail();
                                                        $properties = [
@@ -51,7 +50,7 @@ class AlttpTechCommand {
                                                                $properties['image'] = [
                                                                        'url' => url($tech->gif),
                                                                ];
-                                                       } else if ($tech->image) {
+                                                       } elseif ($tech->image) {
                                                                $properties['image'] = [
                                                                        'url' => url($tech->image),
                                                                ];
@@ -74,13 +73,16 @@ class AlttpTechCommand {
                                        $phrase = $interaction->data->options['tech']->options['name']->value;
                                } catch (\Exception $e) {
                                }
-                               $tech = Technique::where('type', '=', 'tech')->where('index', '=', 1)->whereNotNull('name');
+                               $tech = Technique::query()
+                                       ->where('type', '=', 'tech')
+                                       ->where('index', '=', 1)
+                                       ->whereNotNull('name');
                                if (!empty($phrase)) {
                                        if ($lang == 'en') {
                                                $tech->where('title', 'LIKE', '%'.$phrase.'%');
                                                $tech->orWhere('short', 'LIKE', '%'.$phrase.'%');
                                        } else {
-                                               $tech = $tech->whereHas('translations', function ($query) use ($lang, $phrase) {
+                                               $tech->whereHas('translations', function ($query) use ($lang, $phrase) {
                                                        $query->where('locale', '=', $lang);
                                                        $query->where(function ($subquery) use ($phrase) {
                                                                $subquery->where('title', 'LIKE', '%'.$phrase.'%');
@@ -95,7 +97,9 @@ class AlttpTechCommand {
                                                'name' => $t->getTranslatedProperty('title', $lang),
                                                'value' => $t->name,
                                        ];
-                                       if (count($choices) == 25) break;
+                                       if (count($choices) == 25) {
+                                               break;
+                                       }
                                }
                                usort($choices, function ($a, $b) use ($phrase) {
                                        $a_head = stripos($a['name'], $phrase) === 0;
diff --git a/app/DiscordAppCommands/EventsCommand.php b/app/DiscordAppCommands/EventsCommand.php
new file mode 100644 (file)
index 0000000..9a273c2
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+namespace App\DiscordAppCommands;
+
+use Discord\Builders\CommandBuilder;
+use Discord\Discord;
+
+class EventsCommand {
+
+       public static function create(Discord $discord): void {
+               $command = CommandBuilder::new();
+               $command->setName('events');
+               $command->setDescription('Event subscriptions');
+               $command->setDescriptionLocalization('de', 'Event Abonnements');
+               $command->setDmPermission(false);
+               $command->setDefaultMemberPermissions("0");
+               $command->addOption(EventsShowCommand::create($discord));
+               $discord->application->commands->save(
+                       $discord->application->commands->create($command->toArray())
+               );
+       }
+
+       public static function listen(Discord $discord): void {
+               EventsShowCommand::listen('events', $discord);
+       }
+
+}
diff --git a/app/DiscordAppCommands/EventsShowCommand.php b/app/DiscordAppCommands/EventsShowCommand.php
new file mode 100644 (file)
index 0000000..f7b177d
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+namespace App\DiscordAppCommands;
+
+use App\Models\DiscordGuild;
+use App\Models\Technique;
+use Discord\Builders\MessageBuilder;
+use Discord\Discord;
+use Discord\Parts\Interactions\Command\Option;
+use Discord\Parts\Interactions\Interaction;
+
+class EventsShowCommand {
+
+       public static function create(Discord $discord): Option {
+               $command = new Option($discord);
+               $command->setType(Option::SUB_COMMAND);
+               $command->setName('show');
+               $command->setDescription('Show what events your server subscribes to on alttp.localhorst.tv');
+               return $command;
+       }
+
+       public static function listen(string $parent, Discord $discord): void {
+               $discord->listenCommand(
+                       [$parent, 'show'],
+                       function (Interaction $interaction) use ($discord) {
+                               $interaction
+                                       ->acknowledgeWithResponse()
+                                       ->done(function () use ($discord, $interaction) {
+                                               try {
+                                                       // TODO: translation
+                                                       $lang = Technique::locale2lang($interaction->locale);
+                                                       $guild = DiscordGuild::query()->where('guild_id', '=', $interaction->guild_id)->firstOrFail();
+                                                       $embed = $guild->getSubscriptionsEmbed($discord);
+                                                       $message = MessageBuilder::new();
+                                                       $message->addEmbed($embed);
+                                                       $interaction->updateOriginalResponse($message);
+                                               } catch (\Throwable $e) {
+                                                       $message = MessageBuilder::new();
+                                                       $message->setContent('Error: '.$e->getMessage());
+                                                       $interaction->updateOriginalResponse($message);
+                                               }
+                                       });
+                       },
+               );
+       }
+
+}
index c210babefb917b7eab220e7677c7a8929e5bae33..bfbd2d5d7b9ecc1c9682969b55c527ee7eff8d93 100644 (file)
@@ -2,24 +2,25 @@
 
 namespace App\Models;
 
+use Discord\Discord;
+use Discord\Parts\Embed\Embed;
 use Discord\Parts\Guild\Guild;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 
-class DiscordGuild extends Model
-{
+class DiscordGuild extends Model {
 
        use HasFactory;
 
-       public static function onUpstreamCreate(Guild $guild) {
+       public static function onUpstreamCreate(Guild $guild): void {
                static::sync($guild);
        }
 
-       public static function onUpstreamUpdate(Guild $guild) {
+       public static function onUpstreamUpdate(Guild $guild): void {
                static::sync($guild);
        }
 
-       public static function sync(Guild $guild) {
+       public static function sync(Guild $guild): void {
                $model = static::firstOrNew([
                        'guild_id' => $guild->id,
                ]);
@@ -72,6 +73,45 @@ class DiscordGuild extends Model
                return $this->hasMany(DiscordGuildUserSubscription::class);
        }
 
+
+       public function getSubscriptionsEmbed(Discord $discord): Embed {
+               $any = count($this->event_subscriptions) + count($this->ladder_subscriptions) + count($this->user_subscriptions);
+               $title = 'Creating events for:';
+               $text = '';
+               if (count($this->event_subscriptions)) {
+                       $text .= "Events:\n";
+                       foreach ($this->event_subscriptions as $esub) {
+                               $text .= '- ['.$esub->event->title.']('.$esub->event->getURL().")\n";
+                       }
+                       $text .= "\n";
+               }
+               if (count($this->ladder_subscriptions)) {
+                       $text .= "Ladder Modes:\n";
+                       foreach ($this->ladder_subscriptions as $lsub) {
+                               $text .= '- '.$lsub->step_ladder_mode->name.' ('.substr($lsub->step_ladder_mode->ext_id, 11).")\n";
+                       }
+                       $text .= "\n";
+               }
+               if (count($this->user_subscriptions)) {
+                       $text .= "Runners:\n";
+                       foreach ($this->user_subscriptions as $usub) {
+                               $text .= '- '.$usub->user->getName()."\n";
+                       }
+                       $text .= "\n";
+               }
+               if (empty($text)) {
+                       $text = 'Nothing, really';
+               }
+               $properties = [
+                       'color' => 0x389c38,
+                       'description' => $text,
+                       'title' => $title,
+                       'type' => 'rich',
+               ];
+               return new Embed($discord, $properties);
+       }
+
+
        protected $fillable = [
                'guild_id',
        ];
index f63a558fdde63583880b302c960abda1b90a0138..6ebaa626fd69e47839756bb9d4dd2bb51433cd08 100644 (file)
@@ -36,6 +36,10 @@ class Event extends Model
                return '';
        }
 
+       public function getURL(): string {
+               return url('/events/'.$this->name);
+       }
+
        protected $casts = [
                'end' => 'datetime',
                'start' => 'datetime',