Add native error reporting functions and slash boilerplate
This commit is contained in:
parent
0aa75af3e4
commit
c3270a5c63
@ -19,7 +19,12 @@
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
/*
|
||||
use danog\MadelineProto\API;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
|
||||
/*
|
||||
* Various ways to load MadelineProto
|
||||
*/
|
||||
if (\file_exists('vendor/autoload.php')) {
|
||||
@ -34,13 +39,40 @@ if (\file_exists('vendor/autoload.php')) {
|
||||
/**
|
||||
* Event handler class.
|
||||
*/
|
||||
class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
class MyEventHandler extends EventHandler
|
||||
{
|
||||
public function onUpdateNewChannelMessage($update)
|
||||
/**
|
||||
* @var int|string Username or ID of bot admin
|
||||
*/
|
||||
const ADMIN = "danogentili"; // Change this
|
||||
/**
|
||||
* Get peer(s) where to report errors.
|
||||
*
|
||||
* @return int|string|array
|
||||
*/
|
||||
public function getReportPeers()
|
||||
{
|
||||
yield $this->onUpdateNewMessage($update);
|
||||
return [self::ADMIN];
|
||||
}
|
||||
public function onUpdateNewMessage($update)
|
||||
/**
|
||||
* Handle updates from supergroups and channels.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onUpdateNewChannelMessage(array $update): \Generator
|
||||
{
|
||||
return $this->onUpdateNewMessage($update);
|
||||
}
|
||||
/**
|
||||
* Handle updates from users.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function onUpdateNewMessage(array $update): \Generator
|
||||
{
|
||||
if ($update['message']['_'] === 'messageEmpty' || $update['message']['out'] ?? false) {
|
||||
return;
|
||||
@ -51,21 +83,13 @@ class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
yield $this->messages->sendMessage(['peer' => $update, 'message' => "<code>$res</code>", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']);
|
||||
if (isset($update['message']['media']) && $update['message']['media']['_'] !== 'messageMediaGame') {
|
||||
yield $this->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
|
||||
/* '_' => 'inputMediaUploadedDocument',
|
||||
'file' => $update,
|
||||
'attributes' => [
|
||||
['_' => 'documentAttributeFilename', 'file_name' => 'document.txt']
|
||||
]
|
||||
],]);*/
|
||||
//yield $this->downloadToDir($update, '/tmp');
|
||||
}
|
||||
} catch (\danog\MadelineProto\RPCErrorException $e) {
|
||||
$this->logger((string) $e, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
} catch (\danog\MadelineProto\Exception $e) {
|
||||
} catch (RPCErrorException $e) {
|
||||
$this->report("Surfaced: $e");
|
||||
} catch (Exception $e) {
|
||||
if (\stripos($e->getMessage(), 'invalid constructor given') === false) {
|
||||
$this->logger((string) $e, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
$this->report("Surfaced: $e");
|
||||
}
|
||||
//$this->messages->sendMessage(['peer' => '@danogentili', 'message' => $e->getCode().': '.$e->getMessage().PHP_EOL.$e->getTraceAsString()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,11 +102,8 @@ $settings = [
|
||||
],
|
||||
];
|
||||
|
||||
$MadelineProto = new \danog\MadelineProto\API('bot.madeline', $settings);
|
||||
$MadelineProto->async(true);
|
||||
$MadelineProto->loop(function () use ($MadelineProto) {
|
||||
yield $MadelineProto->start();
|
||||
yield $MadelineProto->setEventHandler('\EventHandler');
|
||||
});
|
||||
$MadelineProto = new API('bot.madeline', $settings);
|
||||
|
||||
$MadelineProto->loop();
|
||||
// Reduce boilerplate with new wrapper method.
|
||||
// Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
|
||||
$MadelineProto->startAndLoop(MyEventHandler::class);
|
||||
|
@ -19,7 +19,12 @@
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
\set_include_path(\get_include_path().':'.\realpath(\dirname(__FILE__).'/MadelineProto/'));
|
||||
use danog\MadelineProto\API;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
use danog\MadelineProto\Tools;
|
||||
|
||||
/*
|
||||
* Various ways to load MadelineProto
|
||||
@ -34,54 +39,89 @@ if (\file_exists(__DIR__.'/vendor/autoload.php')) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Combined event handler class.
|
||||
* Event handler class.
|
||||
*/
|
||||
class EventHandler extends \danog\MadelineProto\CombinedEventHandler
|
||||
class MyEventHandler extends EventHandler
|
||||
{
|
||||
public function onUpdateNewChannelMessage($update, $path)
|
||||
/**
|
||||
* @var int|string Username or ID of bot admin
|
||||
*/
|
||||
const ADMIN = "danogentili"; // Change this
|
||||
/**
|
||||
* Get peer(s) where to report errors.
|
||||
*
|
||||
* @return int|string|array
|
||||
*/
|
||||
public function getReportPeers()
|
||||
{
|
||||
yield $this->onUpdateNewMessage($update, $path);
|
||||
return [self::ADMIN];
|
||||
}
|
||||
public function onUpdateNewMessage($update, $path)
|
||||
/**
|
||||
* Handle updates from supergroups and channels.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onUpdateNewChannelMessage(array $update): \Generator
|
||||
{
|
||||
if (isset($update['message']['out']) && $update['message']['out']) {
|
||||
return $this->onUpdateNewMessage($update);
|
||||
}
|
||||
/**
|
||||
* Handle updates from users.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function onUpdateNewMessage(array $update): \Generator
|
||||
{
|
||||
if ($update['message']['_'] === 'messageEmpty' || $update['message']['out'] ?? false) {
|
||||
return;
|
||||
}
|
||||
$MadelineProto = $this->{$path};
|
||||
|
||||
if (isset($update['message']['media'])) {
|
||||
yield $MadelineProto->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
|
||||
}
|
||||
|
||||
$res = \json_encode($update, JSON_PRETTY_PRINT);
|
||||
if ($res == '') {
|
||||
$res = \var_export($update, true);
|
||||
}
|
||||
yield $MadelineProto->sleep(3);
|
||||
|
||||
try {
|
||||
yield $MadelineProto->messages->sendMessage(['peer' => $update, 'message' => "<code>$res</code>\n\nDopo 3 secondi, in modo asincrono", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']); //'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
|
||||
} catch (\danog\MadelineProto\RPCErrorException $e) {
|
||||
\danog\MadelineProto\Logger::log((string) $e, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
} catch (\danog\MadelineProto\Exception $e) {
|
||||
\danog\MadelineProto\Logger::log((string) $e, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
//$MadelineProto->messages->sendMessage(['peer' => '@danogentili', 'message' => $e->getCode().': '.$e->getMessage().PHP_EOL.$e->getTraceAsString()]);
|
||||
yield $this->messages->sendMessage(['peer' => $update, 'message' => "<code>$res</code>", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']);
|
||||
if (isset($update['message']['media']) && $update['message']['media']['_'] !== 'messageMediaGame') {
|
||||
yield $this->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
|
||||
}
|
||||
} catch (RPCErrorException $e) {
|
||||
$this->report("Surfaced: $e");
|
||||
} catch (Exception $e) {
|
||||
if (\stripos($e->getMessage(), 'invalid constructor given') === false) {
|
||||
$this->report("Surfaced: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$settings = ['logger' => ['logger_level' => 5]];
|
||||
$CombinedMadelineProto = new \danog\MadelineProto\CombinedAPI('combined_session.madeline', ['bot.madeline' => $settings, 'user.madeline' => $settings]);
|
||||
$MadelineProtos = [];
|
||||
foreach ([
|
||||
'bot.madeline' => 'Bot Login',
|
||||
'user.madeline' => 'Userbot login',
|
||||
'user2.madeline' => 'Userbot login (2)'
|
||||
] as $session => $message) {
|
||||
Logger::log($message, Logger::WARNING);
|
||||
$MadelineProto = new API($session);
|
||||
$MadelineProto->async(true);
|
||||
$MadelineProto->loop(function () use ($MadelineProto) {
|
||||
yield $MadelineProto->start();
|
||||
yield $MadelineProto->setEventHandler(MyEventHandler::class);
|
||||
});
|
||||
$MadelineProtos []= $MadelineProto->loopFork();
|
||||
}
|
||||
|
||||
\danog\MadelineProto\Logger::log('Bot login', \danog\MadelineProto\Logger::WARNING);
|
||||
$CombinedMadelineProto->instances['bot.madeline']->start();
|
||||
|
||||
\danog\MadelineProto\Logger::log('Userbot login');
|
||||
$CombinedMadelineProto->instances['user.madeline']->start();
|
||||
|
||||
$CombinedMadelineProto->setEventHandler('\EventHandler');
|
||||
$CombinedMadelineProto->loop();
|
||||
|
||||
$CombinedMadelineProto->async(true);
|
||||
$CombinedMadelineProto->setEventHandler('\EventHandler');
|
||||
$CombinedMadelineProto->loop();
|
||||
do {
|
||||
$thrown = false;
|
||||
try {
|
||||
Tools::wait(Tools::all($MadelineProtos));
|
||||
} catch (\Throwable $e) {
|
||||
$thrown = true;
|
||||
try {
|
||||
$MadelineProto->report("Surfaced: $e");
|
||||
} catch (\Throwable $e) {
|
||||
$MadelineProto->logger((string) $e, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
} while ($thrown);
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
use Amp\Http\Server\HttpServer;
|
||||
use danog\MadelineProto\API;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\MTProtoTools\Files;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
use danog\MadelineProto\Tools;
|
||||
@ -49,7 +48,21 @@ class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
"Usage: `https://example.com file name.ext`\n\n".
|
||||
"I can also rename Telegram files, just send me any file and I will rename it!\n\n".
|
||||
"Max 1.5GB, parallel upload and download powered by @MadelineProto.";
|
||||
const ADMIN = 'danogentili';
|
||||
|
||||
/**
|
||||
* @var int|string Username or ID of bot admin
|
||||
*/
|
||||
const ADMIN = 'danogentili'; // Change this
|
||||
|
||||
/**
|
||||
* Get peer(s) where to report errors.
|
||||
*
|
||||
* @return int|string|array
|
||||
*/
|
||||
public function getReportPeers()
|
||||
{
|
||||
return [self::ADMIN];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to allow uploads.
|
||||
@ -65,26 +78,32 @@ class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param API $API API
|
||||
* @param ?API $API API
|
||||
*/
|
||||
public function __construct($API)
|
||||
public function __construct(?API $API)
|
||||
{
|
||||
$this->UPLOAD = \class_exists(HttpServer::class);
|
||||
parent::__construct($API);
|
||||
}
|
||||
public function onUpdateNewChannelMessage($update)
|
||||
/**
|
||||
* Handle updates from channels and supergroups.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function onUpdateNewChannelMessage(array $update)
|
||||
{
|
||||
//yield $this->onUpdateNewMessage($update);
|
||||
}
|
||||
public function report(string $message)
|
||||
{
|
||||
try {
|
||||
$this->messages->sendMessage(['peer' => self::ADMIN, 'message' => $message]);
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger("While reporting: $e", Logger::FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
public function onUpdateNewMessage($update)
|
||||
/**
|
||||
* Handle updates from users.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function onUpdateNewMessage(array $update): \Generator
|
||||
{
|
||||
if ($update['message']['out'] ?? false) {
|
||||
return;
|
||||
@ -111,7 +130,7 @@ class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
unset($this->states[$peerId]);
|
||||
$update = Files::extractBotAPIFile(yield $this->MTProtoToBotAPI($update));
|
||||
$file = [$update['file_size'], $update['mime_type']];
|
||||
\var_dump($update['file_id'].'.'.Tools::base64urlEncode(json_encode($file))."/".$update['file_name']);
|
||||
\var_dump($update['file_id'].'.'.Tools::base64urlEncode(\json_encode($file))."/".$update['file_name']);
|
||||
return;
|
||||
}
|
||||
yield $this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a new name for this file: ', 'reply_to_msg_id' => $messageId]);
|
||||
@ -220,19 +239,7 @@ $settings = [
|
||||
];
|
||||
|
||||
$MadelineProto = new \danog\MadelineProto\API(($argv[1] ?? 'bot').'.madeline', $settings);
|
||||
$MadelineProto->async(true);
|
||||
while (true) {
|
||||
try {
|
||||
$MadelineProto->loop(function () use ($MadelineProto) {
|
||||
yield $MadelineProto->start();
|
||||
yield $MadelineProto->setEventHandler('\EventHandler');
|
||||
});
|
||||
$MadelineProto->loop();
|
||||
} catch (\Throwable $e) {
|
||||
try {
|
||||
$MadelineProto->logger("Surfaced: $e");
|
||||
$MadelineProto->getEventHandler(['async' => false])->report("Surfaced: $e");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reduce boilerplate with new wrapper method.
|
||||
// Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
|
||||
$MadelineProto->startAndLoop(MyEventHandler::class);
|
||||
|
@ -33,11 +33,48 @@ if (\file_exists(__DIR__.'/../vendor/autoload.php')) {
|
||||
include 'madeline.php';
|
||||
}
|
||||
|
||||
class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
class SecretHandler extends \danog\MadelineProto\EventHandler
|
||||
{
|
||||
private $sent = [-440592694 => true];
|
||||
|
||||
public function onUpdateNewEncryptedMessage($update)
|
||||
public function __construct($API)
|
||||
{
|
||||
parent::__construct($API);
|
||||
$this->sent = [];
|
||||
}
|
||||
/**
|
||||
* @var int|string Username or ID of bot admin
|
||||
*/
|
||||
const ADMIN = "danogentili"; // Change this
|
||||
/**
|
||||
* Get peer(s) where to report errors.
|
||||
*
|
||||
* @return int|string|array
|
||||
*/
|
||||
public function getReportPeers()
|
||||
{
|
||||
return [self::ADMIN];
|
||||
}
|
||||
/**
|
||||
* Handle updates from users.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function onUpdateNewMessage(array $update): \Generator
|
||||
{
|
||||
if ($update['message']['message'] === 'request') {
|
||||
yield $this->requestSecretChat($update);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Handle secret chat messages.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function onUpdateNewEncryptedMessage(array $update): \Generator
|
||||
{
|
||||
try {
|
||||
if (isset($update['message']['decrypted_message']['media'])) {
|
||||
@ -72,14 +109,14 @@ class EventHandler extends \danog\MadelineProto\EventHandler
|
||||
$secret_media['voice'] = ['peer' => $update, 'file' => 'tests/mosconi.mp3', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'file_name' => 'mosconi.mp3', 'size' => \filesize('tests/mosconi.mp3'), 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => true, 'duration' => 1, 'title' => 'AH NON LO SO IO', 'performer' => 'IL DIO GERMANO MOSCONI']]]]];
|
||||
|
||||
foreach ($secret_media as $type => $smessage) {
|
||||
yield $this->messages->sendEncryptedFile($smessage);
|
||||
$promises = $this->messages->sendEncryptedFile($smessage);
|
||||
}
|
||||
yield $promises;
|
||||
|
||||
$i = 0;
|
||||
while ($i < 10) {
|
||||
$this->logger("SENDING MESSAGE $i TO ".$update['message']['chat_id']);
|
||||
// You can also use the sendEncrypted parameter for more options in secret chats
|
||||
//yield $this->messages->sendEncrypted(['peer' => $update, 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => (string) ($i++)]]);
|
||||
yield $this->messages->sendMessage(['peer' => $update, 'message' => (string) ($i++)]);
|
||||
}
|
||||
$this->sent[$update['message']['chat_id']] = true;
|
||||
@ -102,7 +139,5 @@ $settings = \json_decode(\getenv('MTPROTO_SETTINGS'), true) ?: [];
|
||||
|
||||
$MadelineProto = new \danog\MadelineProto\API('s.madeline', $settings);
|
||||
|
||||
$MadelineProto->start();
|
||||
$MadelineProto->setEventHandler('\EventHandler');
|
||||
$MadelineProto->async(true);
|
||||
$MadelineProto->loop();
|
||||
// Reduce boilerplate with new wrapper method
|
||||
$MadelineProto->startAndLoop(MyEventHandler::class);
|
||||
|
@ -405,4 +405,35 @@ class API extends InternalDoc
|
||||
return $wrote;
|
||||
})());
|
||||
}
|
||||
|
||||
/**
|
||||
* Start MadelineProto and the event handler (enables async).
|
||||
*
|
||||
* Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
|
||||
*
|
||||
* @param string $eventHandler Event handler class name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function startAndLoop(string $eventHandler): void
|
||||
{
|
||||
$this->async(true);
|
||||
do {
|
||||
$thrown = false;
|
||||
try {
|
||||
$this->loop(function () use ($eventHandler) {
|
||||
yield $this->start();
|
||||
yield $this->setEventHandler($eventHandler);
|
||||
});
|
||||
$this->loop();
|
||||
} catch (\Throwable $e) {
|
||||
$thrown = true;
|
||||
try {
|
||||
$this->report("Surfaced: $e");
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger((string) $e, Logger::FATAL_ERROR);
|
||||
}
|
||||
}
|
||||
} while ($thrown);
|
||||
}
|
||||
}
|
||||
|
@ -97,15 +97,15 @@ abstract class AbstractAPIFactory extends AsyncConstruct
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
$yielded = Tools::call($this->__call_async($name, $arguments));
|
||||
$async = !$this->lua && ((is_array(\end($arguments)) ? \end($arguments) : [])['async'] ?? ($this->async && $name !== 'loop'));
|
||||
$async = !$this->lua && ((\is_array(\end($arguments)) ? \end($arguments) : [])['async'] ?? ($this->async && $name !== 'loop'));
|
||||
if ($async) {
|
||||
return $yielded;
|
||||
}
|
||||
$yielded = Tools::wait($yielded);
|
||||
if (!$this->lua) {
|
||||
return Tools::wait($yielded);
|
||||
return $yielded;
|
||||
}
|
||||
try {
|
||||
$yielded = Tools::wait($yielded);
|
||||
Lua::convertObjects($yielded);
|
||||
return $yielded;
|
||||
} catch (\Throwable $e) {
|
||||
@ -128,9 +128,6 @@ abstract class AbstractAPIFactory extends AsyncConstruct
|
||||
yield from $this->initAsynchronously();
|
||||
$this->API->logger->logger('Finished init asynchronously');
|
||||
}
|
||||
if (Magic::isFork() && !Magic::$processed_fork) {
|
||||
throw new Exception('Forking not supported, use async logic, instead: https://docs.madelineproto.xyz/docs/ASYNC.html');
|
||||
}
|
||||
if (!$this->API) {
|
||||
throw new Exception('API did not init!');
|
||||
}
|
||||
@ -160,7 +157,7 @@ abstract class AbstractAPIFactory extends AsyncConstruct
|
||||
$args = isset($arguments[0]) && \is_array($arguments[0]) ? $arguments[0] : [];
|
||||
return yield from $this->API->methodCallAsyncRead($name, $args, $aargs);
|
||||
}
|
||||
$res = yield $this->methods[$lower_name](...$arguments);
|
||||
$res = $this->methods[$lower_name](...$arguments);
|
||||
return $res instanceof \Generator ? yield from $res : yield $res;
|
||||
}
|
||||
/**
|
||||
|
@ -41,4 +41,13 @@ class EventHandler extends InternalDoc
|
||||
$this->{$namespace} = new APIFactory($namespace, $this->API, $this->async);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get peers where to send error reports.
|
||||
*
|
||||
* @return array|string|int
|
||||
*/
|
||||
public function getReportPeers()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -4215,6 +4215,37 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Check if has report peers.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasReportPeers(): bool
|
||||
{
|
||||
return $this->API->hasReportPeers();
|
||||
}
|
||||
/**
|
||||
* Set peer(s) where to send errors occurred in the event loop.
|
||||
*
|
||||
* @param int|string $userOrId Username(s) or peer ID(s)
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function setReportPeers($userOrId, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$userOrId, $extra]);
|
||||
}
|
||||
/**
|
||||
* Report an error to the previously set peer.
|
||||
*
|
||||
* @param string $message Error to report
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function report(string $message, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$message, $extra]);
|
||||
}
|
||||
/**
|
||||
* Call method and wait asynchronously for response.
|
||||
*
|
||||
@ -5293,6 +5324,17 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return \danog\MadelineProto\MTProto::rleEncode($string);
|
||||
}
|
||||
/**
|
||||
* Inflate stripped photosize to full JPG payload.
|
||||
*
|
||||
* @param string $stripped Stripped photosize
|
||||
*
|
||||
* @return string JPG payload
|
||||
*/
|
||||
public function inflateStripped(string $stripped): string
|
||||
{
|
||||
return \danog\MadelineProto\MTProto::inflateStripped($stripped);
|
||||
}
|
||||
/**
|
||||
* Get final element of array.
|
||||
*
|
||||
@ -5460,6 +5502,17 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
$this->API->setEventHandler($event_handler);
|
||||
}
|
||||
/**
|
||||
* Unset event handler.
|
||||
*
|
||||
* @param bool $disableUpdateHandling Whether to also disable internal update handling (will cause errors, otherwise will simply use the NOOP handler)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unsetEventHandler(bool $disableUpdateHandling = false): void
|
||||
{
|
||||
$this->API->unsetEventHandler($disableUpdateHandling);
|
||||
}
|
||||
/**
|
||||
* Get event handler.
|
||||
*
|
||||
@ -5469,6 +5522,15 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->API->getEventHandler();
|
||||
}
|
||||
/**
|
||||
* Check if an event handler instance is present.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasEventHandler(): bool
|
||||
{
|
||||
return $this->API->hasEventHandler();
|
||||
}
|
||||
/**
|
||||
* Set webhook update handler.
|
||||
*
|
||||
@ -5591,17 +5653,6 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$params, $extra]);
|
||||
}
|
||||
/**
|
||||
* Set loop callback (DEPRECATED).
|
||||
*
|
||||
* @param callable $callback Callback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLoopCallback($callback): void
|
||||
{
|
||||
$this->API->setLoopCallback($callback);
|
||||
}
|
||||
/**
|
||||
* Start MadelineProto's update handling loop, or run the provided async callable.
|
||||
*
|
||||
@ -5623,15 +5674,22 @@ class InternalDoc extends APIFactory
|
||||
$this->API->stop();
|
||||
}
|
||||
/**
|
||||
* Start MadelineProto's update handling loop in background, or run the provided async callable.
|
||||
* Restart update loop.
|
||||
*
|
||||
* @param callable $callback Async callable to run
|
||||
*
|
||||
* @return mixed
|
||||
* @return void
|
||||
*/
|
||||
public function loopFork($callback = null): void
|
||||
public function restart(): void
|
||||
{
|
||||
$this->API->loopFork($callback);
|
||||
$this->API->restart();
|
||||
}
|
||||
/**
|
||||
* Start MadelineProto's update handling loop in background.
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function loopFork(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Close connection with client, connected via web.
|
||||
|
File diff suppressed because one or more lines are too long
@ -79,7 +79,7 @@ trait Files
|
||||
} elseif (\is_array($file)) {
|
||||
return yield from $this->uploadFromTgfile($file, $cb, $encrypted);
|
||||
}
|
||||
if (\is_resource($file) || (is_object($file) && $file instanceof InputStream)) {
|
||||
if (\is_resource($file) || (\is_object($file) && $file instanceof InputStream)) {
|
||||
return yield from $this->uploadFromStream($file, 0, '', $fileName, $cb, $encrypted);
|
||||
}
|
||||
if (!$this->settings['upload']['allow_automatic_upload']) {
|
||||
@ -212,7 +212,7 @@ trait Files
|
||||
yield $stream->seek(0, \SEEK_END);
|
||||
$size = yield $stream->tell();
|
||||
yield $stream->seek(0);
|
||||
} else if (!$size) {
|
||||
} elseif (!$size) {
|
||||
$this->logger->logger("No content length for stream, caching first");
|
||||
$body = $stream;
|
||||
$stream = new BlockingFile(\fopen('php://temp', 'r+b'), 'php://temp', 'r+b');
|
||||
|
@ -240,7 +240,8 @@ trait BotAPI
|
||||
if (isset($data['fwd_from']['channel_id'])) {
|
||||
try {
|
||||
$newd['forward_from_chat'] = yield from $this->getPwrChat(PeerHandler::toSupergroup($data['fwd_from']['channel_id']));
|
||||
} catch (\Throwable $e) {}
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
}
|
||||
if (isset($data['fwd_from']['date'])) {
|
||||
$newd['forward_date'] = $data['fwd_from']['date'];
|
||||
|
@ -739,10 +739,10 @@ trait Tools
|
||||
return $new;
|
||||
}
|
||||
/**
|
||||
* Inflate stripped photosize to full JPG payload
|
||||
* Inflate stripped photosize to full JPG payload.
|
||||
*
|
||||
* @param string $stripped Stripped photosize
|
||||
*
|
||||
*
|
||||
* @return string JPG payload
|
||||
*/
|
||||
public static function inflateStripped(string $stripped): string
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
namespace danog\MadelineProto\Wrappers;
|
||||
|
||||
use EventHandler;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
|
||||
/**
|
||||
* Event handler.
|
||||
@ -35,7 +35,7 @@ trait Events
|
||||
/**
|
||||
* Event handler instance.
|
||||
*
|
||||
* @var \danog\MadelineProto\EventHandler
|
||||
* @var EventHandler
|
||||
*/
|
||||
private $event_handler_instance;
|
||||
/**
|
||||
@ -78,6 +78,7 @@ trait Events
|
||||
$this->event_handler_methods[$method_name] = [$this->event_handler_instance, $method];
|
||||
}
|
||||
}
|
||||
$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;
|
||||
@ -86,12 +87,12 @@ trait Events
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Unset event handler.
|
||||
*
|
||||
* @param bool $disableUpdateHandling Whether to also disable internal update handling (will cause errors, otherwise will simply use the NOOP handler)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
* Unset event handler.
|
||||
*
|
||||
* @param bool $disableUpdateHandling Whether to also disable internal update handling (will cause errors, otherwise will simply use the NOOP handler)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unsetEventHandler(bool $disableUpdateHandling = false): void
|
||||
{
|
||||
$this->event_handler = null;
|
||||
@ -107,10 +108,19 @@ trait Events
|
||||
*
|
||||
* @return EventHandler
|
||||
*/
|
||||
public function getEventHandler(): \danog\MadelineProto\EventHandler
|
||||
public function getEventHandler(): EventHandler
|
||||
{
|
||||
return $this->event_handler_instance;
|
||||
}
|
||||
/**
|
||||
* Check if an event handler instance is present.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasEventHandler(): bool
|
||||
{
|
||||
return isset($this->event_handler_instance);
|
||||
}
|
||||
/**
|
||||
* Event update handler.
|
||||
*
|
||||
|
@ -35,17 +35,7 @@ trait Loop
|
||||
* @var boolean
|
||||
*/
|
||||
private $stopLoop = false;
|
||||
/**
|
||||
* Set loop callback (DEPRECATED).
|
||||
*
|
||||
* @param callable $callback Callback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLoopCallback($callback): void
|
||||
{
|
||||
$this->loop_callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start MadelineProto's update handling loop, or run the provided async callable.
|
||||
*
|
||||
@ -75,7 +65,9 @@ trait Loop
|
||||
if (!\is_callable($this->loop_callback) || \is_array($this->loop_callback) && $this->loop_callback[1] === 'onLoop' && !\method_exists(...$this->loop_callback)) {
|
||||
$this->loop_callback = null;
|
||||
}
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
|
||||
static $inited = false;
|
||||
if (PHP_SAPI !== 'cli' && !$inited) {
|
||||
$needs_restart = true;
|
||||
try {
|
||||
\set_time_limit(-1);
|
||||
@ -83,11 +75,11 @@ trait Loop
|
||||
$needs_restart = true;
|
||||
}
|
||||
if (isset($_REQUEST['MadelineSelfRestart'])) {
|
||||
$this->logger->logger("Self-restarted, restart token " . $_REQUEST['MadelineSelfRestart']);
|
||||
$this->logger->logger("Self-restarted, restart token ".$_REQUEST['MadelineSelfRestart']);
|
||||
}
|
||||
$this->logger->logger($needs_restart ? 'Will self-restart' : 'Will not self-restart');
|
||||
$backtrace = \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
$lockfile = \dirname(\end($backtrace)['file']) . '/bot' . $this->authorization['user']['id'] . '.lock';
|
||||
$lockfile = \dirname(\end($backtrace)['file']).'/bot'.$this->authorization['user']['id'].'.lock';
|
||||
unset($backtrace);
|
||||
$try_locking = true;
|
||||
if (!\file_exists($lockfile)) {
|
||||
@ -120,7 +112,7 @@ trait Loop
|
||||
if ($needs_restart) {
|
||||
$logger =& $this->logger;
|
||||
Shutdown::addCallback(static function () use (&$logger) {
|
||||
$address = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 'tls' : 'tcp') . '://' . $_SERVER['SERVER_NAME'];
|
||||
$address = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 'tls' : 'tcp').'://'.$_SERVER['SERVER_NAME'];
|
||||
$port = $_SERVER['SERVER_PORT'];
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$params = $_GET;
|
||||
@ -128,7 +120,7 @@ trait Loop
|
||||
$url = \explode('?', $uri, 2)[0] ?? '';
|
||||
$query = \http_build_query($params);
|
||||
$uri = \implode('?', [$url, $query]);
|
||||
$payload = $_SERVER['REQUEST_METHOD'] . ' ' . $uri . ' ' . $_SERVER['SERVER_PROTOCOL'] . "\r\n" . 'Host: ' . $_SERVER['SERVER_NAME'] . "\r\n\r\n";
|
||||
$payload = $_SERVER['REQUEST_METHOD'].' '.$uri.' '.$_SERVER['SERVER_PROTOCOL']."\r\n".'Host: '.$_SERVER['SERVER_NAME']."\r\n\r\n";
|
||||
$logger->logger("Connecting to {$address}:{$port}");
|
||||
$a = \fsockopen($address, $port);
|
||||
$logger->logger("Sending self-restart payload");
|
||||
@ -140,6 +132,7 @@ trait Loop
|
||||
}, 'restarter');
|
||||
}
|
||||
$this->closeConnection('Bot was started');
|
||||
$inited = true;
|
||||
}
|
||||
if (!$this->settings['updates']['handle_updates']) {
|
||||
$this->settings['updates']['handle_updates'] = true;
|
||||
@ -179,15 +172,22 @@ trait Loop
|
||||
$this->signalUpdate();
|
||||
}
|
||||
/**
|
||||
* Start MadelineProto's update handling loop in background, or run the provided async callable.
|
||||
* Restart update loop.
|
||||
*
|
||||
* @param callable $callback Async callable to run
|
||||
*
|
||||
* @return mixed
|
||||
* @return void
|
||||
*/
|
||||
public function loopFork($callback = null): void
|
||||
public function restart(): void
|
||||
{
|
||||
Tools::callFork($this->loop($callback));
|
||||
$this->stop();
|
||||
}
|
||||
/**
|
||||
* Start MadelineProto's update handling loop in background.
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function loopFork(): Promise
|
||||
{
|
||||
return Tools::callFork($this->loop());
|
||||
}
|
||||
/**
|
||||
* Close connection with client, connected via web.
|
||||
@ -203,14 +203,14 @@ trait Loop
|
||||
}
|
||||
$this->logger->logger($message);
|
||||
$buffer = @\ob_get_clean() ?: '';
|
||||
$buffer .= '<html><body><h1>' . \htmlentities($message) . '</h1></body></html>';
|
||||
$buffer .= '<html><body><h1>'.\htmlentities($message).'</h1></body></html>';
|
||||
\ignore_user_abort(true);
|
||||
\header('Connection: close');
|
||||
\header('Content-Type: text/html');
|
||||
echo $buffer;
|
||||
\flush();
|
||||
$GLOBALS['exited'] = true;
|
||||
if (\function_exists(\fastcgi_finish_request::class)) {
|
||||
if (\function_exists('fastcgi_finish_request')) {
|
||||
\fastcgi_finish_request();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user