diff --git a/README.md b/README.md index 75d17b773..99e71fecb 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ You can find examples for nearly every MadelineProto function in * [Handling updates (new messages)](https://docs.madelineproto.xyz/docs/UPDATES.html) * [Self-restart on webhosts](https://docs.madelineproto.xyz/docs/UPDATES.html#self-restart-on-webhosts) * [Async Event driven](https://docs.madelineproto.xyz/docs/UPDATES.html#async-event-driven) - * [Multi-account: Async Combined Event driven update handling](https://docs.madelineproto.xyz/docs/UPDATES.html#async-combined-event-driven) + * [Multi-account: Async Event driven](https://docs.madelineproto.xyz/docs/UPDATES.html#async-event-driven) * [Async Callback](https://docs.madelineproto.xyz/docs/UPDATES.html#async-callback) * [Noop (default)](https://docs.madelineproto.xyz/docs/UPDATES.html#noop) * [Fetch all updates from the beginning](https://docs.madelineproto.xyz/docs/UPDATES.html#fetch-all-updates-from-the-beginning) diff --git a/examples/bot.php b/examples/bot.php index 53c714e4a..5ea4851cf 100755 --- a/examples/bot.php +++ b/examples/bot.php @@ -19,7 +19,6 @@ * @link https://docs.madelineproto.xyz MadelineProto documentation */ -use Amp\Loop; use danog\MadelineProto\API; use danog\MadelineProto\EventHandler; use danog\MadelineProto\Exception; diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index 8e994bcfa..61e123eca 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -128,7 +128,7 @@ class API extends InternalDoc public function __construct_async(string $session, array $settings = []): \Generator { Logger::constructorFromSettings($settings); - $session = Absolute::absolute($session); + $this->session = $session = Absolute::absolute($session); if ($unserialized = yield from Serialization::legacyUnserialize($session)) { $unserialized->storage = $unserialized->storage ?? []; $unserialized->session = $session; @@ -235,10 +235,7 @@ class API extends InternalDoc } catch (\Throwable $e) { $thrown = true; $this->logger((string) $e, Logger::FATAL_ERROR); - try { - $this->report("Surfaced: $e"); - } catch (\Throwable $e) { - } + $this->report("Surfaced: $e"); } } while ($thrown); } diff --git a/src/danog/MadelineProto/InternalDoc.php b/src/danog/MadelineProto/InternalDoc.php index 81af9d74a..bf254e13d 100644 --- a/src/danog/MadelineProto/InternalDoc.php +++ b/src/danog/MadelineProto/InternalDoc.php @@ -5540,11 +5540,11 @@ class InternalDoc extends APIFactory * * @param string|EventHandler $event_handler Event handler * - * @return void + * @return \Generator */ - public function setEventHandler($event_handler): void + public function setEventHandler($event_handler, array $extra = []) { - $this->API->setEventHandler($event_handler); + return $this->__call(__FUNCTION__, [$event_handler, $extra]); } /** * Unset event handler. diff --git a/src/danog/MadelineProto/Logger.php b/src/danog/MadelineProto/Logger.php index 6663a6271..67fd273e8 100644 --- a/src/danog/MadelineProto/Logger.php +++ b/src/danog/MadelineProto/Logger.php @@ -70,6 +70,12 @@ class Logger * @var string */ public $newline = "\n"; + /** + * Logfile + * + * @var ResourceOutputStream + */ + public $stdout; /** * Default logger instance. * diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 87f4bd005..a897dc3c4 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -20,6 +20,7 @@ namespace danog\MadelineProto; use Amp\Dns\Resolver; +use Amp\File\StatCache; use Amp\Http\Client\DelegateHttpClient; use Amp\Loop; use danog\MadelineProto\Async\AsyncConstruct; @@ -34,6 +35,10 @@ use danog\MadelineProto\MTProtoTools\UpdatesState; use danog\MadelineProto\TL\TL; use danog\MadelineProto\TL\TLCallback; +use function Amp\File\exists; +use function Amp\File\size; +use function Amp\File\unlink as unlinkAsync; + /** * Manages all of the mtproto stuff. */ @@ -1709,7 +1714,7 @@ class MTProto extends AsyncConstruct implements TLCallback $userOrId = [$userOrId]; } foreach ($userOrId as &$peer) { - $peer = yield from $this->getInfo($userOrId)['bot_api_id']; + $peer = (yield from $this->getInfo($peer))['bot_api_id']; } $this->reportDest = $userOrId; } @@ -1725,13 +1730,45 @@ class MTProto extends AsyncConstruct implements TLCallback if (!$this->reportDest) { return; } + $file = null; + if ($this->settings['logger']['logger'] === Logger::FILE_LOGGER) { + $path = $this->settings['logger']['logger_param']; + StatCache::clear($path); + if (!yield exists($path)) { + $message = "!!! WARNING !!!\nThe logfile does not exist, please DO NOT delete the logfile to avoid errors in MadelineProto!\n\n$message"; + } elseif (!yield size($path)) { + $message = "!!! WARNING !!!\nThe logfile is empty, please DO NOT delete the logfile to avoid errors in MadelineProto!\n\n$message"; + } else { + $file = yield from $this->methodCallAsyncRead( + 'messages.uploadMedia', + [ + 'peer' => $this->reportDest[0], + 'media' => [ + '_' => 'inputMediaUploadedDocument', + 'file' => $path, + 'attributes' => [ + ['_' => 'documentAttributeFilename', 'file_name' => 'MadelineProto.log'] + ] + ] + ] + ); + } + } + $sent = true; foreach ($this->reportDest as $id) { try { yield from $this->methodCallAsyncRead('messages.sendMessage', ['peer' => $id, 'message' => $message]); + yield from $this->methodCallAsyncRead('messages.sendMedia', ['peer' => $id, 'media' => $file]); + $sent &= true; } catch (\Throwable $e) { + $sent &= false; $this->logger("While reporting to $id: $e", Logger::FATAL_ERROR); } } + if ($sent && $file) { + ftruncate($this->logger->stdout->getResource(), 0); + $this->logger->logger("Reported!"); + } } /** * Get full list of MTProto and API methods. @@ -1820,10 +1857,6 @@ class MTProto extends AsyncConstruct implements TLCallback { $vars = \get_object_vars($this); unset($vars['full_chats'], $vars['chats'], $vars['referenceDatabase'], $vars['minDatabase'], $vars['TL']); - - - - return $vars; } const ALL_MIMES = ['webp' => [0 => 'image/webp'], 'png' => [0 => 'image/png', 1 => 'image/x-png'], 'bmp' => [0 => 'image/bmp', 1 => 'image/x-bmp', 2 => 'image/x-bitmap', 3 => 'image/x-xbitmap', 4 => 'image/x-win-bitmap', 5 => 'image/x-windows-bmp', 6 => 'image/ms-bmp', 7 => 'image/x-ms-bmp', 8 => 'application/bmp', 9 => 'application/x-bmp', 10 => 'application/x-win-bitmap'], 'gif' => [0 => 'image/gif'], 'jpeg' => [0 => 'image/jpeg', 1 => 'image/pjpeg'], 'xspf' => [0 => 'application/xspf+xml'], 'vlc' => [0 => 'application/videolan'], 'wmv' => [0 => 'video/x-ms-wmv', 1 => 'video/x-ms-asf'], 'au' => [0 => 'audio/x-au'], 'ac3' => [0 => 'audio/ac3'], 'flac' => [0 => 'audio/x-flac'], 'ogg' => [0 => 'audio/ogg', 1 => 'video/ogg', 2 => 'application/ogg'], 'kmz' => [0 => 'application/vnd.google-earth.kmz'], 'kml' => [0 => 'application/vnd.google-earth.kml+xml'], 'rtx' => [0 => 'text/richtext'], 'rtf' => [0 => 'text/rtf'], 'jar' => [0 => 'application/java-archive', 1 => 'application/x-java-application', 2 => 'application/x-jar'], 'zip' => [0 => 'application/x-zip', 1 => 'application/zip', 2 => 'application/x-zip-compressed', 3 => 'application/s-compressed', 4 => 'multipart/x-zip'], '7zip' => [0 => 'application/x-compressed'], 'xml' => [0 => 'application/xml', 1 => 'text/xml'], 'svg' => [0 => 'image/svg+xml'], '3g2' => [0 => 'video/3gpp2'], '3gp' => [0 => 'video/3gp', 1 => 'video/3gpp'], 'mp4' => [0 => 'video/mp4'], 'm4a' => [0 => 'audio/x-m4a'], 'f4v' => [0 => 'video/x-f4v'], 'flv' => [0 => 'video/x-flv'], 'webm' => [0 => 'video/webm'], 'aac' => [0 => 'audio/x-acc'], 'm4u' => [0 => 'application/vnd.mpegurl'], 'pdf' => [0 => 'application/pdf', 1 => 'application/octet-stream'], 'pptx' => [0 => 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], 'ppt' => [0 => 'application/powerpoint', 1 => 'application/vnd.ms-powerpoint', 2 => 'application/vnd.ms-office', 3 => 'application/msword'], 'docx' => [0 => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], 'xlsx' => [0 => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 1 => 'application/vnd.ms-excel'], 'xl' => [0 => 'application/excel'], 'xls' => [0 => 'application/msexcel', 1 => 'application/x-msexcel', 2 => 'application/x-ms-excel', 3 => 'application/x-excel', 4 => 'application/x-dos_ms_excel', 5 => 'application/xls', 6 => 'application/x-xls'], 'xsl' => [0 => 'text/xsl'], 'mpeg' => [0 => 'video/mpeg'], 'mov' => [0 => 'video/quicktime'], 'avi' => [0 => 'video/x-msvideo', 1 => 'video/msvideo', 2 => 'video/avi', 3 => 'application/x-troff-msvideo'], 'movie' => [0 => 'video/x-sgi-movie'], 'log' => [0 => 'text/x-log'], 'txt' => [0 => 'text/plain'], 'css' => [0 => 'text/css'], 'html' => [0 => 'text/html'], 'wav' => [0 => 'audio/x-wav', 1 => 'audio/wave', 2 => 'audio/wav'], 'xhtml' => [0 => 'application/xhtml+xml'], 'tar' => [0 => 'application/x-tar'], 'tgz' => [0 => 'application/x-gzip-compressed'], 'psd' => [0 => 'application/x-photoshop', 1 => 'image/vnd.adobe.photoshop'], 'exe' => [0 => 'application/x-msdownload'], 'js' => [0 => 'application/x-javascript'], 'mp3' => [0 => 'audio/mpeg', 1 => 'audio/mpg', 2 => 'audio/mpeg3', 3 => 'audio/mp3'], 'rar' => [0 => 'application/x-rar', 1 => 'application/rar', 2 => 'application/x-rar-compressed'], 'gzip' => [0 => 'application/x-gzip'], 'hqx' => [0 => 'application/mac-binhex40', 1 => 'application/mac-binhex', 2 => 'application/x-binhex40', 3 => 'application/x-mac-binhex40'], 'cpt' => [0 => 'application/mac-compactpro'], 'bin' => [0 => 'application/macbinary', 1 => 'application/mac-binary', 2 => 'application/x-binary', 3 => 'application/x-macbinary'], 'oda' => [0 => 'application/oda'], 'ai' => [0 => 'application/postscript'], 'smil' => [0 => 'application/smil'], 'mif' => [0 => 'application/vnd.mif'], 'wbxml' => [0 => 'application/wbxml'], 'wmlc' => [0 => 'application/wmlc'], 'dcr' => [0 => 'application/x-director'], 'dvi' => [0 => 'application/x-dvi'], 'gtar' => [0 => 'application/x-gtar'], 'php' => [0 => 'application/x-httpd-php', 1 => 'application/php', 2 => 'application/x-php', 3 => 'text/php', 4 => 'text/x-php', 5 => 'application/x-httpd-php-source'], 'swf' => [0 => 'application/x-shockwave-flash'], 'sit' => [0 => 'application/x-stuffit'], 'z' => [0 => 'application/x-compress'], 'mid' => [0 => 'audio/midi'], 'aif' => [0 => 'audio/x-aiff', 1 => 'audio/aiff'], 'ram' => [0 => 'audio/x-pn-realaudio'], 'rpm' => [0 => 'audio/x-pn-realaudio-plugin'], 'ra' => [0 => 'audio/x-realaudio'], 'rv' => [0 => 'video/vnd.rn-realvideo'], 'jp2' => [0 => 'image/jp2', 1 => 'video/mj2', 2 => 'image/jpx', 3 => 'image/jpm'], 'tiff' => [0 => 'image/tiff'], 'eml' => [0 => 'message/rfc822'], 'pem' => [0 => 'application/x-x509-user-cert', 1 => 'application/x-pem-file'], 'p10' => [0 => 'application/x-pkcs10', 1 => 'application/pkcs10'], 'p12' => [0 => 'application/x-pkcs12'], 'p7a' => [0 => 'application/x-pkcs7-signature'], 'p7c' => [0 => 'application/pkcs7-mime', 1 => 'application/x-pkcs7-mime'], 'p7r' => [0 => 'application/x-pkcs7-certreqresp'], 'p7s' => [0 => 'application/pkcs7-signature'], 'crt' => [0 => 'application/x-x509-ca-cert', 1 => 'application/pkix-cert'], 'crl' => [0 => 'application/pkix-crl', 1 => 'application/pkcs-crl'], 'pgp' => [0 => 'application/pgp'], 'gpg' => [0 => 'application/gpg-keys'], 'rsa' => [0 => 'application/x-pkcs7'], 'ics' => [0 => 'text/calendar'], 'zsh' => [0 => 'text/x-scriptzsh'], 'cdr' => [0 => 'application/cdr', 1 => 'application/coreldraw', 2 => 'application/x-cdr', 3 => 'application/x-coreldraw', 4 => 'image/cdr', 5 => 'image/x-cdr', 6 => 'zz-application/zz-winassoc-cdr'], 'wma' => [0 => 'audio/x-ms-wma'], 'vcf' => [0 => 'text/x-vcard'], 'srt' => [0 => 'text/srt'], 'vtt' => [0 => 'text/vtt'], 'ico' => [0 => 'image/x-icon', 1 => 'image/x-ico', 2 => 'image/vnd.microsoft.icon'], 'csv' => [0 => 'text/x-comma-separated-values', 1 => 'text/comma-separated-values', 2 => 'application/vnd.msexcel'], 'json' => [0 => 'application/json', 1 => 'text/json']]; diff --git a/src/danog/MadelineProto/Magic.php b/src/danog/MadelineProto/Magic.php index 25d482d18..a009a6a53 100644 --- a/src/danog/MadelineProto/Magic.php +++ b/src/danog/MadelineProto/Magic.php @@ -267,14 +267,14 @@ class Magic self::$altervista = isset($_SERVER['SERVER_ADMIN']) && \strpos($_SERVER['SERVER_ADMIN'], 'altervista.org'); self::$zerowebhost = isset($_SERVER['SERVER_ADMIN']) && \strpos($_SERVER['SERVER_ADMIN'], '000webhost.io'); self::$can_getmypid = !self::$altervista && !self::$zerowebhost; - self::$revision = @\file_get_contents(__DIR__ . '/../../../.git/refs/heads/master'); + self::$revision = @\file_get_contents(__DIR__.'/../../../.git/refs/heads/master'); if (self::$revision) { self::$revision = \trim(self::$revision); $latest = @\file_get_contents('https://phar.madelineproto.xyz/release'); if ($latest) { $latest = self::$revision === \trim($latest) ? '' : ' (AN UPDATE IS REQUIRED)'; } - self::$revision = 'Revision: ' . self::$revision . $latest; + self::$revision = 'Revision: '.self::$revision.$latest; } self::$can_parallel = false; if (PHP_SAPI === 'cli' && !(\class_exists(\Phar::class) && \Phar::running())) { @@ -332,7 +332,7 @@ class Magic try { \error_reporting(E_ALL); \ini_set('log_errors', 1); - \ini_set('error_log', Magic::$script_cwd . '/MadelineProto.log'); + \ini_set('error_log', Magic::$script_cwd.'/MadelineProto.log'); \error_log('Enabled PHP logging'); } catch (\danog\MadelineProto\Exception $e) { //$this->logger->logger('Could not enable PHP logging'); diff --git a/src/danog/MadelineProto/Wrappers/Events.php b/src/danog/MadelineProto/Wrappers/Events.php index 2a8f417a5..0bf64e31b 100644 --- a/src/danog/MadelineProto/Wrappers/Events.php +++ b/src/danog/MadelineProto/Wrappers/Events.php @@ -49,9 +49,9 @@ trait Events * * @param string|EventHandler $event_handler Event handler * - * @return void + * @return \Generator */ - public function setEventHandler($event_handler): void + public function setEventHandler($event_handler): \Generator { if (!\class_exists($event_handler) || !\is_subclass_of($event_handler, '\\danog\\MadelineProto\\EventHandler')) { throw new \danog\MadelineProto\Exception('Wrong event handler was defined'); @@ -80,7 +80,7 @@ trait Events } } } - $this->setReportPeers($this->event_handler_instance->getReportPeers()); + yield from $this->setReportPeers($this->event_handler_instance->getReportPeers()); $this->settings['updates']['callback'] = [$this, 'eventUpdateHandler']; $this->settings['updates']['handle_updates'] = true; $this->settings['updates']['run_callback'] = true; diff --git a/tests/danog/MadelineProto/FileIdTest.php b/tests/danog/MadelineProto/FileIdTest.php index 04750783c..a9331d74f 100644 --- a/tests/danog/MadelineProto/FileIdTest.php +++ b/tests/danog/MadelineProto/FileIdTest.php @@ -25,6 +25,7 @@ class FileIdTest extends TestCase public static function setUpBeforeClass(): void { self::$MadelineProto = new API( + 'testing.madeline', [ 'app_info' => [ 'api_id' => \getenv('API_ID'),