3 namespace App\TwitchBot;
5 use App\Models\ChatLog;
6 use Illuminate\Support\Arr;
7 use Illuminate\Support\Str;
9 class TokenizedMessage {
11 public function __construct($text, $tags = []) {
14 $this->raw = strtolower(preg_replace('/[^\w]/u', '', $text));
15 $this->tokens = preg_split('/\s+/', strtolower(trim($text)));
17 $this->emoteless = $this->text;
18 if (isset($this->tags['emotes']) && !empty($this->tags['emotes'])) {
19 $emotes = explode('/', $this->tags['emotes']);
20 foreach ($emotes as $emote) {
21 $set = explode(':', $emote);
22 $positions = explode(',', $set[1]);
23 foreach ($positions as $position) {
24 $coords = explode('-', $position);
25 $this->emotes[] = strtolower(substr($this->text, $coords[0], $coords[1] - $coords[0] + 1));
26 for ($i = intval($coords[0]); $i <= intval($coords[1]); ++$i) {
27 $this->emoteless[$i] = ' ';
31 $this->emoteless = trim(preg_replace('/\s+/', ' ', $this->emoteless));
33 $this->emoteless_raw = strtolower(preg_replace('/[^\w]/', '', $this->emoteless));
34 $this->emoteless_tokens = preg_split('/\s+/', strtolower($this->emoteless));
37 public static function fromIRC(IRCMessage $msg) {
38 return new self($msg->getText(), $msg->tags);
41 public static function fromLog(ChatLog $log) {
42 return new self($log->params[1], $log->tags);
45 public static function fromString($text, $tags = []) {
46 return new self($text, $tags);
50 public function contains($text) {
51 return Str::contains($this->text, $text);
54 public function containsRaw($text) {
55 return Str::contains($this->raw, $text);
58 public function endsWith($text) {
59 return Str::endsWith($this->text, $text);
62 public function endsWithRaw($text) {
63 return Str::endsWith($this->raw, $text);
66 public function getNumericValue() {
67 return intval($this->text);
70 public function hasEmote($text) {
71 return in_array($text, $this->emotes);
74 public function hasEmoteThatContains($text) {
75 foreach ($this->emotes as $emote) {
76 if (Str::contains($emote, $text)) {
83 public function hasEmoteThatEndsWith($text) {
84 foreach ($this->emotes as $emote) {
85 if (Str::endsWith($emote, $text)) {
92 public function hasEmoteThatStartsOrEndsWith($text) {
93 foreach ($this->emotes as $emote) {
94 if (Str::startsWith($emote, $text) || Str::endsWith($emote, $text)) {
101 public function hasEmoteThatStartsWith($text) {
102 foreach ($this->emotes as $emote) {
103 if (Str::startsWith($emote, $text)) {
110 public function hasToken($text) {
111 return in_array($text, $this->tokens);
114 public function hasTokenThatContains($text) {
115 foreach ($this->tokens as $token) {
116 if (Str::contains($token, $text)) {
123 public function hasTokenThatEndsWith($text) {
124 foreach ($this->tokens as $token) {
125 if (Str::endsWith($token, $text)) {
132 public function hasTokenThatStartsOrEndsWith($text) {
133 foreach ($this->tokens as $token) {
134 if (Str::startsWith($token, $text) || Str::endsWith($token, $text)) {
141 public function hasTokenThatStartsWith($text) {
142 foreach ($this->tokens as $token) {
143 if (Str::startsWith($token, $text)) {
150 public function startsOrEndsWith($text) {
151 return $this->startsWith($text) || $this->endsWith($text);
154 public function startsOrEndsWithRaw($text) {
155 return $this->startsWithRaw($text) || $this->endsWithRaw($text);
158 public function startsWith($text) {
159 return Str::startsWith($this->text, $text);
162 public function startsWithRaw($text) {
163 return Str::startsWith($this->raw, $text);
167 public function isSpammy() {
168 if ($this->startsWith('!')) {
171 if ($this->contains(['€', '$', '@', '://'])) {
174 if ($this->containsRaw(['followers', 'promotion', 'viewers'])) {
177 if ($this->containsRaw('horstie')) {
180 if ($this->containsRaw(['vielendankfürdenraid', 'willkommenaufstarbase47'])) {
187 public function classify() {
188 if (is_null($this->classification)) {
189 if (empty($this->raw)) {
190 $this->classification = 'unclassified';
191 } else if (is_numeric($this->raw)) {
192 $this->classification = 'number';
193 } else if ($this->hasTokenThatStartsOrEndsWith(['gg'])) {
194 $this->classification = 'gg';
195 } else if ($this->containsRaw(['glgl', 'glhf', 'hfgl'])) {
196 $this->classification = 'gl';
197 } else if ($this->containsRaw(['haha', 'hehe', 'hihi', 'kekw', 'lol', 'lul', 'xd']) || $this->hasTokenThatStartsWith(':d')) {
198 $this->classification = 'lol';
199 } else if ($this->startsWithRaw(['ahoi', 'hallo', 'hello', 'huhu']) || $this->hasEmoteThatEndsWith(['hello', 'hi', 'wave']) || $this->hasToken('hi')) {
200 $this->classification = 'hi';
201 } else if ($this->containsRaw(['pog', 'wow'])) {
202 $this->classification = 'pog';
203 } else if ($this->containsRaw(['hype'])) {
204 $this->classification = 'hype';
205 } else if ($this->startsOrEndsWithRaw(['o7']) || $this->hasEmoteThatContains('salut')) {
206 $this->classification = 'o7';
208 $this->classification = 'unclassified';
211 return $this->classification;
220 private $emotes = [];
221 private $emoteless = '';
222 private $emoteless_raw = '';
223 private $emoteless_tokens = [];
225 private $classification = null;