]> git.localhorst.tv Git - alttp.git/blob - app/TwitchBot/TwitchChatBot.php
twitch chat bot controls
[alttp.git] / app / TwitchBot / TwitchChatBot.php
1 <?php
2
3 namespace App\TwitchBot;
4
5 use App\Models\Channel;
6 use App\Models\ChatLog;
7
8 class TwitchChatBot extends TwitchBot {
9
10         public function __construct() {
11                 parent::__construct('horstiebot');
12                 $this->channels = Channel::where('twitch_chat', '!=', '')->where('chat', '=', true)->get();
13                 foreach ($this->channels as $channel) {
14                         $this->notes[$channel->id] = [
15                                 'last_read' => 0,
16                                 'last_write' => time(),
17                                 'read_since_last_write' => 0,
18                                 'wait_msgs' => $this->randomWaitMsgs($channel),
19                                 'wait_time' => $this->randomWaitTime($channel),
20                         ];
21                 }
22                 $this->startTimer();
23                 $this->listenCommands();
24         }
25
26         public function joinChannels() {
27                 $this->getLogger()->info('joining channels');
28                 $names = [];
29                 foreach ($this->channels as $channel) {
30                         $names[] = $channel->twitch_chat;
31                 }
32                 $chunks = array_chunk($names, 10);
33                 foreach ($chunks as $chunk) {
34                         $this->sendIRCMessage(IRCMessage::join($chunk));
35                 }
36         }
37
38         public function logMessage(IRCMessage $msg) {
39                 $channel = $this->getMessageChannel($msg);
40                 if ($channel && !$channel->join) {
41                         $msg->log();
42                 }
43         }
44
45         public function handlePrivMsg(IRCMessage $msg) {
46                 if ($msg->nick == 'horstiebot') return;
47                 $channel = $this->getMessageChannel($msg);
48                 if (!$channel) return;
49                 $this->tagChannelRead($channel);
50         }
51
52
53         private function startTimer() {
54                 $this->getLoop()->addPeriodicTimer(1, function () {
55                         if (!$this->isReady()) return;
56                         foreach ($this->channels as $channel) {
57                                 $this->decideSend($channel);
58                         }
59                 });
60         }
61
62         private function decideSend(Channel $channel) {
63                 $notes = $this->notes[$channel->id];
64                 if ($notes['read_since_last_write'] < $notes['wait_msgs']) {
65                         return;
66                 }
67                 if (time() - $notes['last_write'] < $notes['wait_time']) {
68                         return;
69                 }
70                 if ($notes['read_since_last_write'] == $notes['wait_msgs'] && time() - $notes['last_read'] < 3) {
71                         // don't immediately respond if we crossed the msg threshold last
72                         return;
73                 }
74                 $text = $this->randomMsg($channel);
75                 if (!$text) return;
76                 $this->tagChannelWrite($channel);
77                 $this->sendIRCMessage(IRCMessage::privmsg($channel->twitch_chat, $text));
78         }
79
80         private function randomMsg(Channel $channel) {
81                 $line = ChatLog::where('type', '=', 'chat')
82                         ->where('banned', '=', false)
83                         ->where('created_at', '<', now()->sub(1, 'day'))
84                         ->where(function ($query) use ($channel) {
85                                 $query->whereNull('detected_language');
86                                 $query->orWhereIn('detected_language', $channel->languages);
87                         })
88                         ->inRandomOrder()
89                         ->first();
90                 return $line->text_content;
91         }
92
93         private function randomWaitMsgs(Channel $channel) {
94                 return random_int(1, 10);
95         }
96
97         private function randomWaitTime(Channel $channel) {
98                 return random_int(1, 900);
99         }
100
101         private function tagChannelRead(Channel $channel) {
102                 $this->notes[$channel->id]['last_read'] = time();
103                 ++$this->notes[$channel->id]['read_since_last_write'];
104         }
105
106         private function tagChannelWrite(Channel $channel) {
107                 $this->notes[$channel->id]['last_write'] = time();
108                 $this->notes[$channel->id]['read_since_last_write'] = 0;
109                 $this->notes[$channel->id]['wait_msgs'] = $this->randomWaitMsgs($channel);
110                 $this->notes[$channel->id]['wait_time'] = $this->randomWaitTime($channel);
111         }
112
113         private $channels;
114         private $notes = [];
115
116 }