]> git.localhorst.tv Git - alttp.git/blobdiff - app/TwitchBot/TwitchBot.php
fix reevaluate command class name
[alttp.git] / app / TwitchBot / TwitchBot.php
index 3ca2db9283e6651e521fa2fe4aeaa596d94f9e2e..63f4236f685e92bf659610257e93177a78cf7a11 100644 (file)
@@ -3,6 +3,7 @@
 namespace App\TwitchBot;
 
 use App\Models\Channel;
+use App\Models\TwitchBotCommand;
 use App\Models\TwitchToken;
 use Monolog\Handler\StreamHandler;
 use Monolog\Logger;
@@ -13,17 +14,22 @@ use React\EventLoop\Loop;
 
 class TwitchBot {
 
-       public function __construct() {
+       public function __construct($nick) {
+               $this->nick = $nick;
                $this->logger = new Logger('TwitchBot');
-               $this->logger->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG));
+               $this->logger->pushHandler(new StreamHandler('php://stdout', Logger::INFO));
 
-               $this->token = TwitchToken::firstWhere('nick', 'localhorsttv');
+               $this->token = TwitchToken::firstWhere('nick', $nick);
                if (!$this->token) {
                        throw new \Exception('unable to find access token');
                }
+               if ($this->token->hasExpired()) {
+                       $this->token->refresh();
+               }
 
                $this->connector = new Connector();
                $this->connect();
+               $this->startPinger();
        }
 
        public function getLogger() {
@@ -34,6 +40,10 @@ class TwitchBot {
                return Loop::get();
        }
 
+       public function isReady() {
+               return $this->ready;
+       }
+
        public function run() {
                $this->shutting_down = false;
                $this->getLoop()->run();
@@ -75,16 +85,17 @@ class TwitchBot {
        public function handleWsMessage(Message $message, WebSocket $ws) {
                $irc_messages = explode("\r\n", rtrim($message->getPayload(), "\r\n"));
                foreach ($irc_messages as $irc_message) {
-                       $this->logger->debug('received IRC message '.$irc_message);
+                       $this->logger->info('received IRC message '.$irc_message);
                        $this->handleIRCMessage(IRCMessage::fromString($irc_message));
                }
        }
 
        public function handleWsClose(int $op, string $reason) {
+               $this->ready = false;
                $this->logger->info('websocket connection closed: '.$reason.' ['.$op.']');
                if (!$this->shutting_down) {
-                       $this->logger->info('reconnecting in 10 seconds');
-                       Loop::addTimer(10, [$this, 'connect']);
+                       $this->logger->info('reconnecting in 5 seconds');
+                       Loop::addTimer(5, [$this, 'connect']);
                }
        }
 
@@ -94,14 +105,19 @@ class TwitchBot {
 
 
        public function handleIRCMessage(IRCMessage $msg) {
-               if ($msg->isPrivMsg()) {
-                       $this->handlePrivMsg($msg);
-                       return;
-               }
+               $this->last_contact = time();
                if ($msg->isPing()) {
                        $this->sendIRCMessage($msg->makePong());
                        return;
                }
+               if ($msg->isPong()) {
+                       return;
+               }
+               $this->logMessage($msg);
+               if ($msg->isPrivMsg()) {
+                       $this->handlePrivMsg($msg);
+                       return;
+               }
                if ($msg->isNotice() && $msg->getText() == 'Login authentication failed') {
                        $this->logger->notice('login failed, refreshing access token');
                        $this->token->refresh();
@@ -111,53 +127,78 @@ class TwitchBot {
                if ($msg->command == '001') {
                        // successful login
                        $this->joinChannels();
+                       $this->ready = true;
                        return;
                }
        }
 
-       public function handlePrivMsg(IRCMessage $msg) {
+       public function getMessageChannel(IRCMessage $msg) {
                $target = $msg->getPrivMsgTarget();
-               if ($target[0] != '#') return;
-               $text = $msg->getText();
-               if ($text[0] != '!') return;
-               $channel = Channel::firstWhere('twitch_chat', '=', $target);
-               if (!$channel) return;
-               $this->logger->info('got command '.$text.' on channel '.$channel->title);
+               if (substr($target, 0, 1) !== '#') {
+                       $target = '#'.$target;
+               }
+               return Channel::firstWhere('twitch_chat', '=', $target);
+       }
+
+       public function logMessage(IRCMessage $msg) {
+       }
+
+       public function handlePrivMsg(IRCMessage $msg) {
        }
 
        public function login() {
                $this->ws->send('PASS oauth:'.$this->token->access);
-               $this->ws->send('NICK localhorsttv');
+               $this->ws->send('NICK '.$this->nick);
        }
 
        public function joinChannels() {
-               $this->logger->info('joining channels');
-               $channels = Channel::where('twitch_chat', '!=', '')->get();
-               $names = [];
-               foreach ($channels as $channel) {
-                       $names[] = $channel->twitch_chat;
-               }
-               $chunks = array_chunk($names, 10);
-               foreach ($chunks as $chunk) {
-                       $this->sendIRCMessage(IRCMessage::join($chunk));
-               }
+       }
+
+       private function startPinger() {
+               $this->getLoop()->addPeriodicTimer(15, function () {
+                       if (!$this->ready) return;
+                       if (time() - $this->last_contact < 60) return;
+                       try {
+                               $this->sendIRCMessage(IRCMessage::ping($this->nick));
+                       } catch (\Exception $e) {
+                       }
+               });
        }
 
        public function sendIRCMessage(IRCMessage $msg) {
                $irc_message = $msg->encode();
-               $this->logger->debug('sending IRC message '.$irc_message);
+               $this->logger->info('sending IRC message '.$irc_message);
                $this->ws->send($irc_message);
+               $this->last_contact = time();
+       }
+
+
+       protected function listenCommands() {
+               $this->getLoop()->addPeriodicTimer(1, function () {
+                       if (!$this->isReady()) return;
+                       $command = TwitchBotCommand::where('bot_nick', '=', $this->nick)->where('status', '=', 'pending')->oldest()->first();
+                       if ($command) {
+                               try {
+                                       $command->execute($this);
+                               } catch (\Exception $e) {
+                               }
+                       }
+               });
        }
 
 
        private $logger;
 
+       private $nick;
        private $token;
 
        private $connector;
        private $ws;
+       private $ready = false;
        private $shutting_down = false;
 
+       private $last_contact;
+
 }
 
 ?>