5 use Illuminate\Database\Eloquent\Factories\HasFactory;
6 use Illuminate\Database\Eloquent\Model;
7 use Illuminate\Support\Arr;
8 use Illuminate\Support\Str;
9 use LanguageDetector\LanguageDetector;
11 class ChatLog extends Model {
15 public function channel() {
16 return $this->belongsTo(Channel::class);
19 public function user() {
20 return $this->belongsTo(User::class);
23 public function evaluate() {
24 $this->evaluateUser();
25 $this->evaluateChannel();
27 if (is_null($this->nick)) {
28 $this->type = 'system';
31 if (in_array($this->nick, ['horstiebot', 'localhorsttv'])) {
36 if ($this->command == 'PRIVMSG') {
37 if ($this->isKnownBot()) {
39 } else if (substr($this->params[0], 0, 1) == '#') {
44 $this->text_content = $this->params[1];
45 $this->detectLanguage();
46 if ($this->scanForSpam()) {
49 $this->classification = static::classify($this->text_content);
53 throw new \Exception('unidentified message');
56 public function isKnownBot() {
57 return in_array(strtolower($this->nick), [
62 'pokemoncommunitygame',
70 public static function classify($text) {
72 return 'unclassified';
74 if (is_numeric(trim($text))) {
77 $rawText = strtolower(preg_replace('/[^\w]/', '', $text));
78 $tokenizedText = preg_split('/\s+/', strtolower(trim($text)));
79 if (Str::startsWith($rawText, 'gg') || Str::endsWith($rawText, 'gg')) {
82 if (Str::contains($rawText, ['glgl', 'glhf', 'hfgl'])) {
85 if (Str::contains($rawText, ['haha', 'hehe', 'hihi', 'kekw', 'lol', 'lul', 'xd'])) {
88 if (Str::startsWith($rawText, ['ahoi', 'hallo', 'hello', 'hi', 'huhu']) || Str::endsWith($rawText, ['hi', 'wave'])) {
91 if (Str::contains($rawText, ['pog', 'wow'])) {
94 if (Str::contains($rawText, ['hype'])) {
97 return 'unclassified';
100 protected function evaluateUser() {
103 protected function evaluateChannel() {
104 if (empty($this->params)) {
105 $this->channel()->associate(null);
108 $cname = $this->params[0];
109 if (substr($cname, 0, 1) != '#') {
112 $channel = Channel::firstWhere('twitch_chat', '=', $cname);
113 $this->channel()->associate($channel);
116 protected function detectLanguage() {
117 $languages = ['de', 'en', 'es', 'fr'];
118 if (!is_null($this->channel)) {
119 $languages = array_values($this->channel->languages);
120 if (!in_array('en', $languages)) {
124 $detector = LanguageDetector::detect($this->text_content, $languages);
125 $scores = $detector->getScores();
126 $lang = strval($detector->getLanguage());
127 //var_dump($scores, $lang, $this->text_content);
128 if (is_array($scores) && isset($scores[$lang]) && $scores[$lang] > 0.35) {
129 $this->detected_language = $lang;
133 protected function scanForSpam() {
134 if (substr($this->text_content, 0, 1) == '!') {
137 if (strpos($this->text_content, '$') !== false) {
140 if (strpos($this->text_content, '€') !== false) {
143 if (strpos($this->text_content, '@') !== false) {
146 if (strpos($this->text_content, '://') !== false) {
149 if (is_numeric($this->text_content)) {
152 if (strpos($this->text_content, 'followers') !== false) {
155 if (strpos($this->text_content, 'promotion') !== false) {
158 if (strpos($this->text_content, 'viewers') !== false) {
161 if (strpos($this->text_content, 'view ers') !== false) {
168 'banned' => 'boolean',
171 'user_id' => 'string',
174 protected $fillable = [