diff --git a/app/Espinoso/BrainNode.php b/app/Espinoso/BrainNode.php new file mode 100644 index 0000000..8788631 --- /dev/null +++ b/app/Espinoso/BrainNode.php @@ -0,0 +1,66 @@ +regex = $regex; + $this->reply = $data['reply'] ?? ''; + $this->ignored = collect($data['ignored'] ?? []); + } + + public function matchMessage(Message $message) + { + $this->match = preg_match($this->regex, $message->getText(), $this->matches) === 1; + + return !empty($this->reply) + && $this->shouldResponseTo($message->getFrom()) + && $this->match; + } + + public function pickReply(Message $message) + { + return is_array($this->reply) + ? $this->pickFromBag($message) + : $this->reply; + } + + public function addIgnored(Collection $ignored) { + $this->ignored->merge($ignored); + } + + protected function shouldResponseTo(TelegramUser $from) + { + // TODO + return true; + } + + protected function pickFromBag(Message $message) + { + // FIXME: make a better behavior than simple random + $number = rand(0, count($this->reply) - 1); + + $reply = $this->reply[$number]; + + if (str_contains($reply, ':name:')) { + $reply = str_replace(':name:', $message->getFrom()->getFirstName(), $reply); + } + + return $reply; + } + +} diff --git a/app/Espinoso/Espinoso.php b/app/Espinoso/Espinoso.php new file mode 100644 index 0000000..dc64dbd --- /dev/null +++ b/app/Espinoso/Espinoso.php @@ -0,0 +1,68 @@ +handlers = $handlers; + } + + /** + * @param ApiTelegram $telegram + * @param Message $message + */ + public function executeHandlers(ApiTelegram $telegram, Message $message) + { + $this->getHandlers()->map(function ($handler) use ($telegram) { + return new $handler($this, $telegram); + })->filter(function (EspinosoHandler $handler) use ($message) { + return $handler->shouldHandle($message); + })->each(function (EspinosoHandler $handler) use ($message) { + try { + $handler->handle($message); + } catch (Exception $e) { + $handler->handleError($e, $message); + } + }); + } + + /** + * @return Collection + */ + public function getHandlers(): Collection + { + return $this->handlers; + } + +// public function register(stdClass $update) +// { +// $from = $update->message->from; +// +// $user = TelegramUser::whereTelegramId($from->id)->first(); +// if (!$user) { +// $user = new TelegramUser; +// $user->telegram_id = $from->id; +// } +// +// $user->first_name = $from->first_name ?? ''; +// $user->last_name = $from->last_name ?? ''; +// $user->username = $from->username ?? ''; +// $user->save(); +// } + +} diff --git a/app/Espinoso/Handlers/BardoDelEspinosoHandler.php b/app/Espinoso/Handlers/BardoDelEspinosoHandler.php index 839bb4a..8fdefed 100644 --- a/app/Espinoso/Handlers/BardoDelEspinosoHandler.php +++ b/app/Espinoso/Handlers/BardoDelEspinosoHandler.php @@ -1,21 +1,27 @@ isTextMessage($updates) - && preg_match('/^send me nudes$/i', $updates->message->text) ; - } + /** + * @var string + */ + protected $allow_ignore_prefix = true; + /** + * @var string + */ + protected $pattern = "send me nudes$"; + + protected $signature = "[espi] send me nudes"; + protected $description = "no sé, fijate"; - public function handle($updates, $context = null) + public function handle(Message $message) { - return Telegram::sendPhoto([ - 'chat_id' => $updates->message->chat->id, + return $this->telegram->sendPhoto([ + 'chat_id' => $message->getChat()->getId(), 'photo' => 'https://cdn.drawception.com/images/panels/2012/4-4/FErsE1a6t7-8.png', - 'caption' => 'Acá tenés tu nude, puto del orto!' + 'caption' => 'Acá tenés tu nude, hijo de puta!' ]); } -} \ No newline at end of file +} diff --git a/app/Espinoso/Handlers/BrainHandler.php b/app/Espinoso/Handlers/BrainHandler.php new file mode 100644 index 0000000..eb80451 --- /dev/null +++ b/app/Espinoso/Handlers/BrainHandler.php @@ -0,0 +1,95 @@ +matchedNodes = collect([]); + $this->allNodes = collect(config('brain.patterns'))->map(function ($data, $regex) { + return new BrainNode($regex, $data); + }); + } + + public function shouldHandle(Message $message): bool + { + $this->matchedNodes = $this->allNodes->filter(function ($node) use ($message) { + $node->addIgnored($this->globalIgnored()); + return $node->matchMessage($message); + }); + + return $this->matchedNodes->isNotEmpty(); + } + + public function handle(Message $message) + { + $this->matchedNodes->each(function (BrainNode $node) use ($message) { + $this->telegram->sendMessage([ + 'chat_id' => $message->getChat()->getId(), + 'text' => $node->pickReply($message), + 'parse_mode' => 'Markdown' + ]); + }); + } + + /* + * Internals + */ + + protected function globalIgnored() + { + return collect(config('brain.ignore_to')); + } + +// public function handle(Message $message) +// { +// if ($this->ignoringSender($message->getFrom())) { +// $fromName = $message->getFrom()->getFirstName(); +// $msg = Msg::md("Con vos no hablo porque no viniste al asado $fromName")->build($message); +// $this->telegram->sendMessage($msg); +// return; +// } +// +// foreach ($this->mappings() as $pattern => $response) { +// if ( preg_match($pattern, $message->getText()) ) { +// $msg = $this->buildMessage($response, $pattern, $message); +// $this->telegram->sendMessage($msg); +// } +// } +// } + +// private function buildMessage($response, $pattern, Message $message) +// { +// if ($response instanceof Msg) +// return $response->build($message, $pattern); +// else +// return Msg::plain($response)->build($message, $pattern); +// } +// +// private function mappings() +// { +// return config('espinoso_data.ResponseByMatch.mappings'); +// } +// + +// private function ignoringSender($sender) +// { +// foreach ($this->ignoredNames() as $name) +// if ( preg_match("/$name/i", $sender->first_name) ) +// return true ; +// return false ; +// } + +} diff --git a/app/Espinoso/Handlers/CinemaHandler.php b/app/Espinoso/Handlers/CinemaHandler.php index 8a6cb2f..baf200f 100644 --- a/app/Espinoso/Handlers/CinemaHandler.php +++ b/app/Espinoso/Handlers/CinemaHandler.php @@ -2,17 +2,19 @@ use Illuminate\Support\Str; use App\Facades\GoutteClient; -use Telegram\Bot\Laravel\Facades\Telegram; +use Telegram\Bot\Objects\Message; class CinemaHandler extends EspinosoCommandHandler { - public function shouldHandle($updates, $context = null) - { - return parent::shouldHandle($updates, $context) - && $this->matchCommand('.*\bcine\b.*', $updates); - } + /** + * @var string + */ + protected $pattern = ".{0,100}\b(cine)\b.{0,100}$"; + + protected $signature = "espi cine"; + protected $description = "te muestro que hay para ver en el cine y ponerla"; - public function handle($updates, $context = null) + public function handle(Message $message) { $crawler = GoutteClient::request('GET', config('espinoso.url.cinema')); @@ -25,14 +27,14 @@ public function handle($updates, $context = null) return " - {$movie}"; })->implode("\n"); - $message = "¿La pensás poner? + $response = "¿La pensás poner? ¡Mete Netflix pelotud@, es mas barato! Pero igual podes ver todas estas:\n {$movies}"; - Telegram::sendMessage([ - 'chat_id' => $updates->message->chat->id, - 'text' => $message, + $this->telegram->sendMessage([ + 'chat_id' => $message->getChat()->getId(), + 'text' => $response, ]); } } diff --git a/app/Espinoso/Handlers/EspinosoCommandHandler.php b/app/Espinoso/Handlers/EspinosoCommandHandler.php index 821d637..2427064 100644 --- a/app/Espinoso/Handlers/EspinosoCommandHandler.php +++ b/app/Espinoso/Handlers/EspinosoCommandHandler.php @@ -1,9 +1,13 @@ matchCommand($this->pattern, $message, $this->matches); + } + /** * @param $pattern - * @param $updates + * @param Message $message * @param array|null $matches - * @return int + * @return bool */ - protected function matchCommand($pattern, $updates, array &$matches = null) + protected function matchCommand($pattern, Message $message, array &$matches = null): bool { - $quantifier = $this->allow_ignore_prefix ? '?' : '{1,3}'; - $text = $this->isTextMessage($updates) ? $updates->message->text : ''; + $quantifier = $this->allow_ignore_prefix ? '{0,3}' : '{1,3}'; + $text = $message->getText(); + $pattern = "/{$this->prefix_regex}{$quantifier}{$pattern}/{$this->flags}"; - return preg_match( - "/{$this->prefix_regex}{$quantifier}{$pattern}/{$this->flags}", - $text, - $matches - ); + return preg_match($pattern, $text, $matches) === 1; } } diff --git a/app/Espinoso/Handlers/EspinosoHandler.php b/app/Espinoso/Handlers/EspinosoHandler.php index c1d9c41..9219a28 100644 --- a/app/Espinoso/Handlers/EspinosoHandler.php +++ b/app/Espinoso/Handlers/EspinosoHandler.php @@ -1,47 +1,85 @@ isTextMessage($updates); + return empty($this->signature) ? '' : "*{$this->signature}*\n\t\t\t{$this->description}"; } - protected function isTextMessage($updates) + public function __construct(Espinoso $espinoso, ApiTelegram $telegram) { - return isset($updates->message) && isset($updates->message->text); + $this->espinoso = $espinoso; + $this->telegram = $telegram; + } + + abstract public function shouldHandle(Message $message): bool; + + abstract public function handle(Message $message); + + /** + * @param Message $message + */ + protected function replyNotFound(Message $message) + { + $this->telegram->sendMessage([ + 'chat_id' => $message->getChat()->getId(), + 'text' => 'No encontré una mierda, che', + ]); } - public function handleError(Exception $e, $updates) + /** + * @param Message $message + */ + protected function replyError(Message $message) + { + $this->telegram->sendMessage([ + 'chat_id' => $message->getChat()->getId(), + 'text' => 'Ups! Esta cosa anda como el culo...', + ]); + } + + public function handleError(Exception $e, Message $message) { $clazz = get_called_class(); Log::error($clazz); - Log::error(json_encode($updates)); + Log::error($message); Log::error($e); - $chat = $updates->message->chat->type == 'group' - ? "{$updates->message->chat->title}" - : ($updates->message->chat->type == 'private' - ? "{$updates->message->chat->first_name} (@{$updates->message->chat->username})" - : ""); - $username = isset($updates->message->from->username) - ? " (@{$updates->message->from->username})" - : ''; + $chat = $message->getChat(); + $username = $chat->getUsername() ? " (@{$chat->getUsername()})" : ""; + $fromUser = $chat->getFirstName() . $username; + + // chat could be private, group, supergroup or channel + $fromChat = $chat->getType() == 'private' ? $fromUser : $chat->getTitle(); + $error = "Fuck! Something blow up on {$clazz} - `{$e->getMessage()}` - - *From:* {$updates->message->from->first_name}{$username} - - *Chat:* {$chat} - - *Text:* _{$updates->message->text}_ + - *From:* {$fromUser} + - *Chat:* {$fromChat} + - *Text:* _{$message->getText()}_ View Log for details"; - Telegram::sendMessage([ + $this->telegram->sendMessage([ 'chat_id' => config('espinoso.chat.dev'), 'text' => $error, 'parse_mode' => 'Markdown', @@ -50,7 +88,7 @@ public function handleError(Exception $e, $updates) public function __toString() { - return self::class; + return get_called_class(); } diff --git a/app/Espinoso/Handlers/GitHubHandler.php b/app/Espinoso/Handlers/GitHubHandler.php index 6aae7bd..08a0584 100644 --- a/app/Espinoso/Handlers/GitHubHandler.php +++ b/app/Espinoso/Handlers/GitHubHandler.php @@ -1,7 +1,7 @@ matchCommand($this->pattern, $updates, $matches); - $this->title = $matches['title'] ?? ''; - - return parent::shouldHandle($updates) && $match; - } + protected $signature = "espi issue
(.*?)(<|<\/p>)/ms', $plotPageHtml, 1))); - $releaseinfoHtml = $this->geturl("http://www.imdb.com/title/" . $arr['title_id'] . "/releaseinfo"); - $arr['also_known_as'] = $this->getAkaTitles($releaseinfoHtml); - $arr['release_dates'] = $this->getReleaseDates($releaseinfoHtml); - $arr['recommended_titles'] = $this->getRecommendedTitles($arr['title_id']); - $arr['media_images'] = $this->getMediaImages($arr['title_id']); - $arr['videos'] = $this->getVideos($arr['title_id']); - } - - return $arr; - } - - // Scan all Release Dates. - private function getReleaseDates($html){ - $releaseDates = array(); - foreach($this->match_all('/
(.*?)<\/td>/ms', $r, 1))); - $date = trim(strip_tags($this->match('/ | (.*?)<\/td>/ms', $r, 1))); - array_push($releaseDates, $country . " = " . $date); - } - return array_filter($releaseDates); - } - - // Scan all AKA Titles. - private function getAkaTitles($html){ - $akaTitles = array(); - foreach($this->match_all('/ |
(.*?)<\/td>/ms', $m, 1);
- $akaCountry = trim($akaTitleMatch[0]);
- $akaTitle = trim($akaTitleMatch[1]);
- array_push($akaTitles, $akaTitle . " = " . $akaCountry);
- }
- return array_filter($akaTitles);
- }
-
- // Collect all Media Images.
- private function getMediaImages($titleId){
- $url = "http://www.imdb.com/title/" . $titleId . "/mediaindex";
- $html = $this->geturl($url);
- $media = array();
- $media = array_merge($media, $this->scanMediaImages($html));
- foreach($this->match_all('/ (.*?)<\/div>/msi', $html, 1), 1) as $i) {
- array_push($pics, preg_replace('/_V1\..*?.jpg/ms', "_V1._SY0.jpg", $i));
- }
- return array_filter($pics);
- }
-
- // Get recommended titles by IMDb title id.
- public function getRecommendedTitles($titleId){
- $json = $this->geturl("http://www.imdb.com/widget/recommendations/_ajax/get_more_recs?specs=p13nsims%3A${titleId}");
- $resp = json_decode($json, true);
- $arr = array();
- if(isset($resp["recommendations"])) {
- foreach($resp["recommendations"] as $val) {
- $name = $this->match('/title="(.*?)"/msi', $val['content'], 1);
- $arr[$val['tconst']] = $name;
- }
- }
- return array_filter($arr);
- }
-
- // Get all Videos and Trailers
- public function getVideos($titleId){
- $html = $this->geturl("http://www.imdb.com/title/${titleId}/videogallery");
- $videos = array();
- foreach ($this->match_all('/ .*?match('/ | .*? | .*?\((.*?)\)<\/span>/msi', $m, 1);
- $rating = $this->match('/ | .*?$id, "rank"=>$rank, "title"=>$title, "year"=>$year, "rating"=>$rating, "poster"=>$poster, "url"=>$url);
- $rank++;
- }
- return $top250;
- }
-
- //************************[ Extra Functions ]******************************
-
- // Movie title search on Google, Bing or Ask. If search fails, return FALSE.
- private function getIMDbIdFromSearch($title, $engine = "google"){
- switch ($engine) {
- case "google": $nextEngine = "bing"; break;
- case "bing": $nextEngine = "ask"; break;
- case "ask": $nextEngine = FALSE; break;
- case FALSE: return NULL;
- default: return NULL;
- }
- $url = "http://www.${engine}.com/search?q=imdb+" . rawurlencode($title);
- $ids = $this->match_all('/ | |