mirror of
https://github.com/danog/telerpc.git
synced 2024-12-02 09:37:51 +01:00
Compare commits
6 Commits
2d297398fc
...
74f2a26f92
Author | SHA1 | Date | |
---|---|---|---|
74f2a26f92 | |||
e35bd3f3a7 | |||
3349db7024 | |||
|
59021cc568 | ||
804d4068e8 | |||
3a3bbb63ca |
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM danog/madelineproto:latest
|
||||
|
||||
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
|
||||
php composer-setup.php && \
|
||||
php -r "unlink('composer-setup.php');" && \
|
||||
mv composer.phar /usr/local/bin/composer && \
|
||||
\
|
||||
apk add procps git unzip github-cli openssh
|
||||
|
||||
RUN git clone https://github.com/danog/telerpc /app
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
|
5
bk.sql
5
bk.sql
@ -14,7 +14,6 @@
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
g
|
||||
--
|
||||
-- Table structure for table `bot_method_invalid`
|
||||
--
|
||||
@ -927,7 +926,7 @@ INSERT INTO `error_descriptions` VALUES
|
||||
('SENSITIVE_CHANGE_FORBIDDEN','You can\'t change your sensitive content settings.'),
|
||||
('SESSION_PASSWORD_NEEDED','2FA is enabled, use a password to login'),
|
||||
('SESSION_TOO_FRESH_%d','This session was created less than 24 hours ago, try again in %d seconds'),
|
||||
i('SETTINGS_INVALID','Invalid settings were provided'),
|
||||
('SETTINGS_INVALID','Invalid settings were provided'),
|
||||
('SHA256_HASH_INVALID','The provided SHA256 hash is invalid'),
|
||||
('SHORT_NAME_INVALID','The specified short name is invalid'),
|
||||
('SHORT_NAME_OCCUPIED','The specified short name is already in use'),
|
||||
@ -2691,7 +2690,7 @@ INSERT INTO `errors` VALUES
|
||||
('USER_BANNED_IN_CHANNEL','messages.sendMedia',400),
|
||||
('USER_BANNED_IN_CHANNEL','messages.sendMessage',400),
|
||||
('USER_BANNED_IN_CHANNEL','messages.sendMultiMedia',400),
|
||||
t('USER_BANNED_IN_CHANNEL','messages.sendReaction',400),
|
||||
('USER_BANNED_IN_CHANNEL','messages.sendReaction',400),
|
||||
('USER_BANNED_IN_CHANNEL','messages.setTyping',400),
|
||||
('USER_BANNED_IN_CHANNEL','messages.updatePinnedMessage',400),
|
||||
('USER_BANNED_IN_CHANNEL','messages.uploadMedia',400),
|
||||
|
@ -3,7 +3,10 @@
|
||||
"description": "RPC Error reporting API",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"danog/madelineproto": "^8"
|
||||
"danog/madelineproto": "^8",
|
||||
"amphp/http-server": "3.x-dev",
|
||||
"amphp/mysql": "3.x-dev",
|
||||
"amphp/http-server-form-parser": "2.x-dev"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"require-dev": {
|
||||
@ -17,6 +20,11 @@
|
||||
"email": "daniil.gentili.dg@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Main.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"cs-fix": "PHP_CS_FIXER_IGNORE_ENV=1 php-cs-fixer fix -v --diff"
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
<?php
|
||||
|
||||
return new PDO('mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=rpc;charset=utf8mb4', 'user', 'pass');
|
||||
use Amp\Mysql\MysqlConfig;
|
||||
|
||||
return new MysqlConfig(
|
||||
host: '/var/run/mysqld/mysqld.sock',
|
||||
user: 'user',
|
||||
password: 'pass',
|
||||
database: 'rpc',
|
||||
);
|
||||
|
7
entrypoint.sh
Executable file
7
entrypoint.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
git pull
|
||||
|
||||
composer update
|
||||
|
||||
php server.php server
|
@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
chdir(__DIR__);
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
include 'src/Main.php';
|
||||
|
||||
(new Main())->run();
|
7
server.php
Normal file
7
server.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
chdir(__DIR__);
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
(new Main())->run(($argv[1] ?? '') === 'serve');
|
270
src/Main.php
270
src/Main.php
@ -1,8 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Amp\Http\HttpStatus;
|
||||
use Amp\Http\Server\DefaultErrorHandler;
|
||||
use Amp\Http\Server\FormParser\Form;
|
||||
use Amp\Http\Server\Request;
|
||||
use Amp\Http\Server\RequestHandler;
|
||||
use Amp\Http\Server\Response;
|
||||
use Amp\Http\Server\SocketHttpServer;
|
||||
use Amp\Log\ConsoleFormatter;
|
||||
use Amp\Log\StreamHandler;
|
||||
use Amp\Mysql\MysqlConnectionPool;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\PsrLogMessageProcessor;
|
||||
|
||||
final class Main
|
||||
use function Amp\ByteStream\getStdout;
|
||||
|
||||
final class Main implements RequestHandler
|
||||
{
|
||||
private const GLOBAL_CODES = [
|
||||
'FLOOD_WAIT_%d' => 420,
|
||||
@ -67,28 +81,36 @@ final class Main
|
||||
'MSG_WAIT_FAILED' => -500,
|
||||
];
|
||||
|
||||
private ?\PDO $pdo = null;
|
||||
private MysqlConnectionPool $pool;
|
||||
|
||||
private function connect(): \PDO
|
||||
public function __construct()
|
||||
{
|
||||
if ($this->pdo !== null) {
|
||||
return $this->pdo;
|
||||
}
|
||||
$this->pdo = include __DIR__.'/../db.php';
|
||||
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
return $this->pdo;
|
||||
$this->pool = new MysqlConnectionPool(include __DIR__.'/../db.php');
|
||||
}
|
||||
|
||||
private static function error(string $message): string
|
||||
private const HEADERS = [
|
||||
'Content-Type' => 'application/json',
|
||||
'access-control-allow-origin' => '*',
|
||||
'access-control-allow-methods' => 'GET, POST, OPTIONS',
|
||||
'access-control-expose-headers' => 'Content-Length,Content-Type,Date,Server,Connection',
|
||||
];
|
||||
|
||||
private static function error(string $message, int $code = HttpStatus::BAD_REQUEST): Response
|
||||
{
|
||||
return \json_encode(['ok' => false, 'description' => $message]);
|
||||
return new Response(
|
||||
$code,
|
||||
self::HEADERS,
|
||||
json_encode(['ok' => false, 'description' => $message])
|
||||
);
|
||||
}
|
||||
|
||||
private static function ok(mixed $result): string
|
||||
private static function ok(mixed $result): Response
|
||||
{
|
||||
return \json_encode(['ok' => true, 'result' => $result]);
|
||||
return new Response(
|
||||
HttpStatus::OK,
|
||||
self::HEADERS,
|
||||
json_encode(['ok' => false, 'result' => $result])
|
||||
);
|
||||
}
|
||||
|
||||
private static function sanitize(string $error): string
|
||||
@ -104,69 +126,53 @@ final class Main
|
||||
|
||||
private function v2(): array
|
||||
{
|
||||
$this->connect();
|
||||
$desc = [];
|
||||
$q = $this->pdo->prepare('SELECT error, description FROM error_descriptions');
|
||||
$q->execute();
|
||||
$q->fetchAll(PDO::FETCH_FUNC, function ($error, $description) use (&$desc) {
|
||||
$q = $this->pool->prepare('SELECT error, description FROM error_descriptions');
|
||||
foreach ($q->execute() as ['error' => $error, 'description' => $description]) {
|
||||
$desc[$error] = $description;
|
||||
});
|
||||
|
||||
$q = $this->pdo->prepare('SELECT method, code, error FROM errors');
|
||||
$q->execute();
|
||||
$r = [];
|
||||
$q->fetchAll(PDO::FETCH_FUNC, function ($method, $code, $error) use (&$r, &$desc) {
|
||||
$code = (int) $code;
|
||||
if ($code === 500) {
|
||||
return;
|
||||
}
|
||||
|
||||
$q = $this->pool->prepare('SELECT method, code, error FROM errors WHERE code != 500');
|
||||
$r = [];
|
||||
foreach ($q->execute() as ['method' => $method, 'code' => $code, 'error' => $error]) {
|
||||
$code = (int) $code;
|
||||
$r[$method][] = [
|
||||
'error_code' => $code,
|
||||
'error_message' => $error,
|
||||
'error_description' => $desc[$error] ?? '',
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
private function v3(): array
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$q = $this->pdo->prepare('SELECT method, code, error FROM errors');
|
||||
$q->execute();
|
||||
$q = $this->pool->prepare('SELECT method, code, error FROM errors');
|
||||
$r = [];
|
||||
$q->fetchAll(PDO::FETCH_FUNC, function ($method, $code, $error) use (&$r) {
|
||||
foreach ($q->execute() as ['method' => $method, 'code' => $code, 'error' => $error]) {
|
||||
$error = self::sanitize($error);
|
||||
$r[(int) $code][$method][$error] = $error;
|
||||
});
|
||||
}
|
||||
|
||||
$hr = [];
|
||||
$q = $this->pdo->prepare('SELECT error, description FROM error_descriptions');
|
||||
$q->execute();
|
||||
$q->fetchAll(PDO::FETCH_FUNC, function ($error, $description) use (&$hr) {
|
||||
$q = $this->pool->prepare('SELECT error, description FROM error_descriptions');
|
||||
foreach ($q->execute() as ['error' => $error, 'description' => $description]) {
|
||||
$error = self::sanitize($error);
|
||||
$description = \str_replace(' X ', ' %d ', $description);
|
||||
$hr[$error] = $description;
|
||||
});
|
||||
}
|
||||
|
||||
return [$r, $hr];
|
||||
}
|
||||
|
||||
private function v4(bool $core = false): array
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$q = $this->pdo->prepare('SELECT method, code, error FROM errors');
|
||||
$q->execute();
|
||||
$q = $this->pool->prepare('SELECT method, code, error FROM errors');
|
||||
$r = [];
|
||||
$errors = [];
|
||||
$bot_only = [];
|
||||
$q->fetchAll(PDO::FETCH_FUNC, function ($method, $code, $error) use (&$r, &$bot_only, &$errors, $core) {
|
||||
if ($core && ($error === 'UPDATE_APP_TO_LOGIN' || $error === 'UPDATE_APP_REQUIRED')) {
|
||||
return;
|
||||
}
|
||||
foreach ($q->execute() as ['method' => $method, 'code' => $code, 'error' => $error]) {
|
||||
$code = (int) $code;
|
||||
$error = self::sanitize($error);
|
||||
if (!\in_array($method, $r[$code][$error] ?? [])) {
|
||||
@ -176,21 +182,17 @@ final class Main
|
||||
if (\in_array($error, ['USER_BOT_REQUIRED', 'USER_BOT_INVALID']) && !\in_array($method, $bot_only) && !\in_array($method, ['bots.setBotInfo', 'bots.getBotInfo'])) {
|
||||
$bot_only[] = $method;
|
||||
}
|
||||
});
|
||||
$hr = [];
|
||||
$q = $this->pdo->prepare('SELECT error, description FROM error_descriptions');
|
||||
$q->execute();
|
||||
$q->fetchAll(PDO::FETCH_FUNC, function ($error, $description) use (&$hr, $core) {
|
||||
if ($core && ($error === 'UPDATE_APP_TO_LOGIN' || $error === 'UPDATE_APP_REQUIRED')) {
|
||||
return;
|
||||
}
|
||||
$hr = [];
|
||||
$q = $this->pool->prepare('SELECT error, description FROM error_descriptions');
|
||||
foreach ($q->execute() as ['error' => $error, 'description' => $description]) {
|
||||
$error = self::sanitize($error);
|
||||
$description = \str_replace(' X ', ' %d ', $description);
|
||||
if ($description !== '' && !\in_array($description[\strlen($description) - 1], ['?', '.', '!'])) {
|
||||
$description .= '.';
|
||||
}
|
||||
$hr[$error] = $description;
|
||||
});
|
||||
}
|
||||
|
||||
$hr['FLOOD_WAIT_%d'] = 'Please wait %d seconds before repeating the action.';
|
||||
|
||||
@ -210,35 +212,35 @@ final class Main
|
||||
|
||||
private function bot(): array
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$q = $this->pdo->prepare('SELECT method FROM bot_method_invalid');
|
||||
$q->execute();
|
||||
$r = $q->fetchAll(PDO::FETCH_COLUMN);
|
||||
$q = $this->pool->prepare('SELECT method FROM bot_method_invalid');
|
||||
$r = [];
|
||||
foreach ($q->execute() as $result) {
|
||||
$r[] = $result['method'];
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
private function cli(): void
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$bot_only = [];
|
||||
$q = $this->pdo->prepare('SELECT error, method FROM errors');
|
||||
$q->execute();
|
||||
$r = $q->fetchAll(PDO::FETCH_COLUMN | PDO::FETCH_GROUP);
|
||||
$q = $this->pool->prepare('SELECT error, method FROM errors');
|
||||
$r = [];
|
||||
foreach ($q->execute() as $result) {
|
||||
$r[$result['error']][] = $result['method'];
|
||||
}
|
||||
foreach ($r as $error => $methods) {
|
||||
$fixed = self::sanitize($error);
|
||||
if ($fixed !== $error) {
|
||||
foreach ($methods as $method) {
|
||||
$q = $this->pdo->prepare('UPDATE errors SET error=? WHERE error=? AND method=?');
|
||||
$q = $this->pool->prepare('UPDATE errors SET error=? WHERE error=? AND method=?');
|
||||
$q->execute([$fixed, $error, $method]);
|
||||
|
||||
$q = $this->pdo->prepare('UPDATE error_descriptions SET error=? WHERE error=?');
|
||||
$q = $this->pool->prepare('UPDATE error_descriptions SET error=? WHERE error=?');
|
||||
$q->execute([$fixed, $error]);
|
||||
|
||||
if (self::sanitize($method) === $fixed) {
|
||||
$q = $this->pdo->prepare('DELETE FROM errors WHERE error=? AND method=?');
|
||||
$q = $this->pool->prepare('DELETE FROM errors WHERE error=? AND method=?');
|
||||
$q->execute([$fixed, $fixed]);
|
||||
echo 'Delete strange '.$error."\n";
|
||||
}
|
||||
@ -247,7 +249,7 @@ final class Main
|
||||
}
|
||||
foreach ($methods as $method) {
|
||||
if (self::sanitize($method) === $fixed) {
|
||||
$q = $this->pdo->prepare('DELETE FROM errors WHERE error=? AND method=?');
|
||||
$q = $this->pool->prepare('DELETE FROM errors WHERE error=? AND method=?');
|
||||
$q->execute([$fixed, $method]);
|
||||
echo 'Delete strange '.$error."\n";
|
||||
}
|
||||
@ -256,9 +258,11 @@ final class Main
|
||||
|
||||
$allowed = [];
|
||||
|
||||
$q = $this->pdo->prepare('SELECT error, method FROM errors');
|
||||
$q->execute();
|
||||
$r = $q->fetchAll(PDO::FETCH_COLUMN | PDO::FETCH_GROUP);
|
||||
$q = $this->pool->prepare('SELECT error, method FROM errors');
|
||||
$r = [];
|
||||
foreach ($q->execute() as $result) {
|
||||
$r[$result['error']][] = $result['method'];
|
||||
}
|
||||
foreach (\array_merge($r, self::GLOBAL_CODES) as $error => $methods) {
|
||||
if (\is_int($methods)) {
|
||||
$allowed[$error] = true;
|
||||
@ -267,7 +271,7 @@ final class Main
|
||||
$anyok = false;
|
||||
foreach ($methods as $method) {
|
||||
if (RPCErrorException::isBad($error, 0, $method)) {
|
||||
$q = $this->pdo->prepare('DELETE FROM errors WHERE error=? AND method=?');
|
||||
$q = $this->pool->prepare('DELETE FROM errors WHERE error=? AND method=?');
|
||||
$q->execute([$error, $method]);
|
||||
echo "Delete $error for $method\n";
|
||||
continue;
|
||||
@ -279,33 +283,31 @@ final class Main
|
||||
}
|
||||
$allowed[$error] = true;
|
||||
|
||||
$q = $this->pdo->prepare('SELECT description FROM error_descriptions WHERE error=?');
|
||||
$q->execute([$error]);
|
||||
if (!$q->rowCount() || !($er = $q->fetchColumn())) {
|
||||
$q = $this->pool->prepare('SELECT description FROM error_descriptions WHERE error=?');
|
||||
$res = $q->execute([$error])->fetchRow();
|
||||
if (!($res['description'] ?? null)) {
|
||||
$methods = \implode(', ', $methods);
|
||||
$description = \readline('Insert description for '.$error.' ('.$methods.'): ');
|
||||
if (\strpos(\readline($error.' - '.$description.' OK? '), 'n') !== false) {
|
||||
continue;
|
||||
}
|
||||
if ($description === 'drop' || $description === 'delete' || $description === 'd') {
|
||||
$q = $this->pdo->prepare('DELETE FROM errors WHERE error=?');
|
||||
$q = $this->pool->prepare('DELETE FROM errors WHERE error=?');
|
||||
$q->execute([$error]);
|
||||
echo 'Delete '.$error."\n";
|
||||
} else {
|
||||
$q = $this->pdo->prepare('REPLACE INTO error_descriptions VALUES (?, ?)');
|
||||
$q = $this->pool->prepare('REPLACE INTO error_descriptions VALUES (?, ?)');
|
||||
$q->execute([$error, $description]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$q = $this->pdo->prepare('SELECT error FROM error_descriptions');
|
||||
$q->execute();
|
||||
$r = $q->fetchAll(PDO::FETCH_COLUMN);
|
||||
foreach ($r as $error) {
|
||||
$q = $this->pool->prepare('SELECT error FROM error_descriptions');
|
||||
foreach ($q->execute() as ['error' => $error]) {
|
||||
if (!isset($allowed[$error])) {
|
||||
$q = $this->pdo->prepare('DELETE FROM errors WHERE error=?');
|
||||
$q = $this->pool->prepare('DELETE FROM errors WHERE error=?');
|
||||
$q->execute([$error]);
|
||||
$q = $this->pdo->prepare('DELETE FROM error_descriptions WHERE error=?');
|
||||
$q = $this->pool->prepare('DELETE FROM error_descriptions WHERE error=?');
|
||||
$q->execute([$error]);
|
||||
echo 'Delete '.$error."\n";
|
||||
}
|
||||
@ -326,54 +328,70 @@ final class Main
|
||||
\file_put_contents('data/core.json', \json_encode(['errors' => $r, 'descriptions' => $hr, 'user_only' => $bot, 'bot_only' => $bot_only]));
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
public function handleRequest(Request $request): Response
|
||||
{
|
||||
if (PHP_SAPI === 'cli') {
|
||||
$form = Form::fromRequest($request);
|
||||
$error = $request->getQueryParameter('error') ?? $form->getValue('error');
|
||||
$code = $request->getQueryParameter('code') ?? $form->getValue('code');
|
||||
$method = $request->getQueryParameter('method') ?? $form->getValue('method');
|
||||
if ($error && $code && $method
|
||||
&& \is_numeric($code)
|
||||
&& !RPCErrorException::isBad(
|
||||
$error,
|
||||
(int) $code,
|
||||
$method
|
||||
)
|
||||
) {
|
||||
$error = self::sanitize($error);
|
||||
|
||||
try {
|
||||
if ($error === $code) {
|
||||
$this->pool->prepare('REPLACE INTO code_errors VALUES (?);')->execute([$code]);
|
||||
} elseif ($error === 'BOT_METHOD_INVALID') {
|
||||
$this->pool->prepare('REPLACE INTO bot_method_invalid VALUES (?);')->execute([$method]);
|
||||
} else {
|
||||
$this->pool->prepare('REPLACE INTO errors VALUES (?, ?, ?);')->execute([$error, $method, $code]);
|
||||
|
||||
$q = $this->pool->prepare('SELECT description FROM error_descriptions WHERE error=?');
|
||||
$result = $q->execute([$error]);
|
||||
if ($row = $result->fetchRow()) {
|
||||
return self::ok($row['description']);
|
||||
}
|
||||
|
||||
return self::error('No description', 404);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return self::error($e->getMessage(), 500);
|
||||
}
|
||||
|
||||
return self::ok(true);
|
||||
}
|
||||
|
||||
return self::error('API for reporting Telegram RPC errors. For localized errors see https://rpc.madelineproto.xyz, to report a new error use the `code`, `method` and `error` GET/POST parameters. Source code at https://github.com/danog/telerpc.');
|
||||
}
|
||||
|
||||
public function run(bool $serve): void
|
||||
{
|
||||
if (!$serve) {
|
||||
$this->cli();
|
||||
exit;
|
||||
}
|
||||
|
||||
\ini_set('log_errors', 1);
|
||||
\ini_set('error_log', '/tmp/rpc.log');
|
||||
\header('Content-Type: application/json');
|
||||
\header('access-control-allow-origin: *');
|
||||
\header('access-control-allow-methods: GET, POST, OPTIONS');
|
||||
\header('access-control-expose-headers: Content-Length,Content-Type,Date,Server,Connection');
|
||||
if (isset($_REQUEST['error'], $_REQUEST['code'], $_REQUEST['method'])
|
||||
&& $_REQUEST['error'] !== ''
|
||||
&& $_REQUEST['method'] !== ''
|
||||
&& \is_numeric($_REQUEST['code'])
|
||||
&& !RPCErrorException::isBad(
|
||||
$_REQUEST['error'],
|
||||
(int) $_REQUEST['code'],
|
||||
$_REQUEST['method']
|
||||
)
|
||||
) {
|
||||
$error = self::sanitize($_REQUEST['error']);
|
||||
$method = $_REQUEST['method'];
|
||||
$code = $_REQUEST['code'];
|
||||
$logHandler = new StreamHandler(getStdout());
|
||||
$logHandler->pushProcessor(new PsrLogMessageProcessor());
|
||||
$logHandler->setFormatter(new ConsoleFormatter());
|
||||
|
||||
try {
|
||||
$this->connect();
|
||||
if ($error === $code) {
|
||||
$this->pdo->prepare('REPLACE INTO code_errors VALUES (?);')->execute([$code]);
|
||||
} elseif ($error === 'BOT_METHOD_INVALID') {
|
||||
$this->pdo->prepare('REPLACE INTO bot_method_invalid VALUES (?);')->execute([$method]);
|
||||
} else {
|
||||
$this->pdo->prepare('REPLACE INTO errors VALUES (?, ?, ?);')->execute([$error, $method, $code]);
|
||||
$logger = new Logger('server');
|
||||
$logger->pushHandler($logHandler);
|
||||
$errorHandler = new DefaultErrorHandler();
|
||||
|
||||
$q = $this->pdo->prepare('SELECT description FROM error_descriptions WHERE error=?');
|
||||
$q->execute([$error]);
|
||||
if ($q->rowCount()) {
|
||||
exit(self::ok($q->fetchColumn()));
|
||||
}
|
||||
exit(self::error('No description'));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
exit(self::error($e->getMessage()));
|
||||
}
|
||||
exit(self::ok(true));
|
||||
}
|
||||
exit(self::error('API for reporting Telegram RPC errors. For localized errors see https://rpc.madelineproto.xyz, to report a new error use the `code`, `method` and `error` GET/POST parameters. Source code at https://github.com/danog/telerpc.'));
|
||||
$server = SocketHttpServer::createForDirectAccess($logger);
|
||||
$server->expose('0.0.0.0:1337');
|
||||
$server->start($this, $errorHandler);
|
||||
|
||||
// Serve requests until SIGINT or SIGTERM is received by the process.
|
||||
Amp\trapSignal([SIGINT, SIGTERM]);
|
||||
|
||||
$server->stop();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user