2020-07-25 20:01:48 +02:00
< ? php
ini_set ( 'log_errors' , 1 );
ini_set ( 'error_log' , '/tmp/rpc.log' );
header ( 'Content-Type: application/json' );
function plsdie ( $message )
{
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => false , 'description' => $message ]));
2020-07-25 20:01:48 +02:00
}
if ( php_sapi_name () === 'cli' ) {
include 'db.php' ;
$pdo -> setAttribute ( PDO :: ATTR_EMULATE_PREPARES , false );
$pdo -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
$q = $pdo -> prepare ( 'SELECT error FROM error_descriptions' );
$q -> execute ();
$r = $q -> fetchAll ( PDO :: FETCH_COLUMN );
foreach ( $r as $error ) {
2021-10-02 17:15:41 +02:00
if ( strpos ( $error , 'INPUT_METHOD_INVALID' ) !== false || strpos ( $error , 'INPUT_CONSTRUCTOR_INVALID' ) !== false || strpos ( $error , 'Received bad_msg_notification' ) === 0 ) {
2020-07-25 20:01:48 +02:00
$q = $pdo -> prepare ( 'DELETE FROM errors WHERE error=?' );
$q -> execute ([ $error ]);
$q = $pdo -> prepare ( 'DELETE FROM error_descriptions WHERE error=?' );
$q -> execute ([ $error ]);
echo 'Delete ' . $error . " \n " ;
}
}
$q = $pdo -> prepare ( 'SELECT error, method FROM errors' );
$q -> execute ();
$r = $q -> fetchAll ( PDO :: FETCH_COLUMN | PDO :: FETCH_GROUP );
foreach ( $r as $error => $methods ) {
2021-10-02 17:15:41 +02:00
if ( strpos ( $error , 'INPUT_METHOD_INVALID' ) !== false || strpos ( $error , 'INPUT_CONSTRUCTOR_INVALID' ) !== false || strpos ( $error , 'Received bad_msg_notification' ) === 0 ) {
2020-07-25 20:01:48 +02:00
$q = $pdo -> prepare ( 'DELETE FROM errors WHERE error=?' );
$q -> execute ([ $error ]);
$q = $pdo -> prepare ( 'DELETE FROM error_descriptions WHERE error=?' );
$q -> execute ([ $error ]);
echo 'Delete ' . $error . " \n " ;
continue ;
}
$q = $pdo -> prepare ( 'SELECT description FROM error_descriptions WHERE error=?' );
$q -> execute ([ $error ]);
if ( ! $q -> rowCount () || ! ( $er = $q -> fetchColumn ())) {
$methods = implode ( ', ' , $methods );
$description = readline ( 'Insert description for ' . $error . ' (' . $methods . '): ' );
if ( strpos ( readline ( $error . ' - ' . $description . ' OK? ' ), 'n' ) !== false ) {
continue ;
}
if ( $description === 'drop' ) {
$q = $pdo -> prepare ( 'DELETE FROM errors WHERE error=?' );
$q -> execute ([ $error ]);
echo 'Delete ' . $error . " \n " ;
} else {
$q = $pdo -> prepare ( 'REPLACE INTO error_descriptions VALUES (?, ?)' );
$q -> execute ([ $error , $description ]);
}
}
}
$map = [ 'all' => 'v1' , 'newall' => 'v2' , 'allv3' => 'v3' , 'allv4' => 'v4' , 'bot' => 'bot' ];
foreach ( $map as $query => $name ) {
2022-02-11 21:09:55 +01:00
$opts = [ 'http' => [ 'method' => 'GET' , 'header' => " Host: rpc.pwrtelegram.xyz \r \n " ]];
2021-10-02 17:15:41 +02:00
$context = stream_context_create ( $opts );
$data = file_get_contents ( " http://localhost/? $query " , false , $context );
2020-07-25 20:01:48 +02:00
$data = json_encode ( json_decode ( $data , true ), JSON_PRETTY_PRINT );
file_put_contents ( " data/ $name .json " , $data );
}
2022-02-11 21:09:55 +01:00
exit ;
2020-07-25 20:01:48 +02:00
}
if ( ! isset ( $_REQUEST [ 'allv4' ]) && ! isset ( $_REQUEST [ 'all' ]) && ! isset ( $_REQUEST [ 'newall' ]) && ! isset ( $_REQUEST [ 'format' ]) && ! isset ( $_REQUEST [ 'allv3' ]) && ! isset ( $_REQUEST [ 'for' ]) && ! isset ( $_REQUEST [ 'rip' ]) && ! isset ( $_REQUEST [ 'code_for' ]) && ! isset ( $_REQUEST [ 'description_for' ]) && ! isset ( $_REQUEST [ 'bot' ]) && ! isset ( $_REQUEST [ 'period' ]) && ! isset ( $_REQUEST [ 'floods' ])) {
if ( ! isset ( $_REQUEST [ 'method' ]) || ! isset ( $_REQUEST [ 'error' ]) || ! isset ( $_REQUEST [ 'code' ]) || $_REQUEST [ 'error' ] === '' || $_REQUEST [ 'method' ] === '' || ! is_numeric ( $_REQUEST [ 'code' ])) {
2022-02-11 21:09:43 +01:00
plsdie ( '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` query string parameters.' );
2020-07-25 20:01:48 +02:00
}
if ( in_array ( $_REQUEST [ 'error' ], [ 'INPUT_CONSTRUCTOR_INVALID_X' , 'USER_DEACTIVATED_BAN' , 'INPUT_METHOD_INVALID' , 'INPUT_FETCH_ERROR' , 'AUTH_KEY_UNREGISTERED' , 'SESSION_REVOKED' , 'USER_DEACTIVATED' ]) || strpos ( $_REQUEST [ 'error' ], 'FLOOD_WAIT_' ) !== false || strpos ( $_REQUEST [ 'error' ], 'EMAIL_UNCONFIRMED_' ) !== false || strpos ( $_REQUEST [ 'error' ], '_MIGRATE_' ) !== false || $_REQUEST [ 'error' ] === 'PEER_FLOOD' || preg_match ( '/FILE_PART_\d*_MISSING/' , $_REQUEST [ 'error' ])) {
plsdie ( 'nop' );
}
}
try {
include 'db.php' ;
$pdo -> setAttribute ( PDO :: ATTR_EMULATE_PREPARES , false );
$pdo -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
if ( isset ( $_REQUEST [ 'period' ]) && isset ( $_REQUEST [ 'method' ]) && isset ( $_REQUEST [ 'number' ])) {
if ( is_numeric ( $_REQUEST [ 'method' ])) {
require 'vendor/autoload.php' ;
$m = \danog\MadelineProto\Serialization :: deserialize ( 'tl.madeline' );
$method = $m -> API -> methods -> find_by_id ( $m -> pack_signed_int ( $_REQUEST [ 'method' ]))[ 'method' ];
if ( $method === false ) {
plsdie ( 'Could not find method by provided ID' );
}
} else {
$method = $_REQUEST [ 'method' ];
}
$number = $_REQUEST [ 'number' ];
$period = $_REQUEST [ 'period' ];
if ( ! isset ( $_REQUEST [ 'additional_key' ])) {
$_REQUEST [ 'additional_key' ] = 'default' ;
}
if ( ! isset ( $_REQUEST [ 'additional_value' ])) {
$_REQUEST [ 'additional_value' ] = 'default' ;
}
$res = $pdo -> prepare ( 'REPLACE INTO flood_wait (method, number, period, additional_key, additional_value) VALUES (?, ?, ?, ?, ?);' ) -> execute ([ $method , $number , $period , $_REQUEST [ 'additional_key' ], $_REQUEST [ 'additional_value' ]]);
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true ]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'for' ])) {
if ( is_numeric ( $_REQUEST [ 'for' ])) {
require 'vendor/autoload.php' ;
$m = \danog\MadelineProto\Serialization :: deserialize ( 'tl.madeline' );
$method = $m -> API -> methods -> find_by_id ( $m -> pack_signed_int ( $_REQUEST [ 'for' ]))[ 'method' ];
if ( $method === false ) {
plsdie ( 'Could not find method by provided ID' );
}
} else {
$method = $_REQUEST [ 'for' ];
}
$q = $pdo -> prepare ( 'SELECT code, error FROM errors WHERE method=?' );
$q -> execute ([ $method ]);
$r = [ 'ok' => true , 'result' => $q -> fetchAll ( PDO :: FETCH_COLUMN | PDO :: FETCH_GROUP )];
foreach ( $r [ 'result' ] as $code => $errors ) {
foreach ( $errors as $error ) {
$q = $pdo -> prepare ( 'SELECT description FROM error_descriptions WHERE error=?' );
$q -> execute ([ $error ]);
if ( $q -> rowCount ()) {
$r [ 'human_result' ][ $code ][ $error ] = $q -> fetchColumn ();
}
}
}
2022-02-11 21:09:55 +01:00
exit ( json_encode ( $r ));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'floods' ])) {
if ( is_numeric ( $_REQUEST [ 'floods' ])) {
require 'vendor/autoload.php' ;
$m = \danog\MadelineProto\Serialization :: deserialize ( 'tl.madeline' );
$method = $m -> API -> methods -> find_by_id ( $m -> pack_signed_int ( $_REQUEST [ 'floods' ]))[ 'method' ];
if ( $method === false ) {
plsdie ( 'Could not find method by provided ID' );
}
} else {
$method = $_REQUEST [ 'floods' ];
}
$q = $pdo -> prepare ( 'SELECT period, number, additional_key, additional_value FROM flood_wait WHERE method=?' );
$q -> execute ([ $method ]);
$r = [ 'ok' => true , 'result' => $q -> fetchAll ( PDO :: FETCH_ASSOC )];
2022-02-11 21:09:55 +01:00
exit ( json_encode ( $r ));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'rip' ])) {
2022-02-23 11:45:18 +01:00
/* $q = $pdo -> prepare ( 'SELECT COUNT(time) FROM rip WHERE time > FROM_UNIXTIME(?)' );
$q -> execute ([ is_int ( $_REQUEST [ 'rip' ]) ? $_REQUEST [ 'rip' ] : time () - 3600 ]); */
exit ( json_encode ([ 'ok' => true ])); //, 'result' => $q->fetchColumn()]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'all' ])) {
$q = $pdo -> prepare ( 'SELECT method, code, error FROM errors' );
$q -> execute ();
$r = [];
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $method , $code , $error ) use ( & $r ) {
if ( $code === 500 ) {
return ;
}
$r [( int ) $code ][ $method ][] = $error ;
});
$q = $pdo -> prepare ( 'SELECT error, description FROM error_descriptions' );
$q -> execute ();
$hr = $q -> fetchAll ( PDO :: FETCH_COLUMN | PDO :: FETCH_GROUP );
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $r , 'human_result' => $hr ]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'newall' ])) {
$desc = [];
$q = $pdo -> prepare ( 'SELECT error, description FROM error_descriptions' );
$q -> execute ();
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $error , $description ) use ( & $desc ) {
$desc [ $error ] = $description ;
});
$q = $pdo -> prepare ( 'SELECT method, code, error FROM errors' );
$q -> execute ();
$r = [];
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $method , $code , $error ) use ( & $r , & $desc ) {
if ( $code === 500 ) {
return ;
}
$r [ $method ][] = [
'error_code' => $code ,
'error_message' => $error ,
'error_description' => $desc [ $error ],
];
});
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $r ]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'allv3' ])) {
$q = $pdo -> prepare ( 'SELECT method, code, error FROM errors' );
$q -> execute ();
$r = [];
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $method , $code , $error ) use ( & $r ) {
$r [( int ) $code ][ $method ][ $error ] = $error ;
});
$hr = [];
$q = $pdo -> prepare ( 'SELECT error, description FROM error_descriptions' );
$q -> execute ();
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $error , $description ) use ( & $hr ) {
$hr [ $error ] = $description ;
});
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $r , 'human_result' => $hr ]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'allv4' ])) {
$q = $pdo -> prepare ( 'SELECT method, code, error FROM errors' );
$q -> execute ();
$r = [];
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $method , $code , $error ) use ( & $r ) {
$code = ( int ) $code ;
$error = preg_replace ( '/_X(["_])?/' , '_%d\1' , $error );
2021-10-02 17:15:41 +02:00
if ( ! in_array ( $method , $r [ $code ][ $error ] ? ? [])) {
$r [ $code ][ $error ][] = $method ;
2020-07-25 20:01:48 +02:00
}
});
$hr = [];
$q = $pdo -> prepare ( 'SELECT error, description FROM error_descriptions' );
$q -> execute ();
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $error , $description ) use ( & $hr ) {
$error = preg_replace ( '/_X(["_])?/' , '_%d\1' , $error );
$description = str_replace ( ' X ' , ' %d ' , $description );
$hr [ $error ] = $description ;
});
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $r , 'human_result' => $hr ]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'format' ])) {
header ( 'Content-Type: text/plain' );
$q = $pdo -> prepare ( 'SELECT code, error FROM errors where method=?' );
$q -> execute ([ $_REQUEST [ 'format' ]]);
$r = " | Code | Type | Description | \n |------|----------|---------------| \n " ;
$temp = [];
$q -> fetchAll ( PDO :: FETCH_FUNC , function ( $code , $error ) use ( & $temp ) {
if ( $code === 500 ) {
return ;
}
if ( $code === - 503 ) {
return ;
}
$temp [ $error ] = $code ;
});
foreach ( $temp as $error => $code ) {
$q = $pdo -> prepare ( 'SELECT description FROM error_descriptions where error=?' );
$q -> execute ([ $error ]);
$r .= " | $code | $error | " . $q -> fetchColumn () . " | \n " ;
}
2022-02-11 21:09:55 +01:00
exit ( $r );
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'bot' ])) {
$q = $pdo -> prepare ( 'SELECT method FROM bot_method_invalid' );
$q -> execute ();
$r = $q -> fetchAll ( PDO :: FETCH_COLUMN );
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $r ]));
2020-07-25 20:01:48 +02:00
}
if ( isset ( $_REQUEST [ 'description_for' ])) {
$q = $pdo -> prepare ( 'SELECT description FROM error_descriptions WHERE error=?' );
$q -> execute ([ $_REQUEST [ 'description_for' ]]);
if ( $q -> rowCount ()) {
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $q -> fetchColumn ()]));
2020-07-25 20:01:48 +02:00
} else {
plsdie ( 'No description' );
}
}
if ( isset ( $_REQUEST [ 'code_for' ])) {
$q = $pdo -> prepare ( 'SELECT code FROM errors WHERE error=?' );
$q -> execute ([ $_REQUEST [ 'code_for' ]]);
if ( $q -> rowCount ()) {
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $q -> fetchColumn ()]));
2020-07-25 20:01:48 +02:00
} else {
plsdie ( 'No such error' );
}
}
if ( $_REQUEST [ 'error' ] === $_REQUEST [ 'code' ]) {
$res = $pdo -> prepare ( 'REPLACE INTO code_errors VALUES (?);' ) -> execute ([ $_REQUEST [ 'code' ]]);
} elseif ( in_array ( $_REQUEST [ 'error' ], [ 'RPC_CALL_FAIL' , 'RPC_MCGET_FAIL' , 'INTERDC_5_CALL_ERROR' , 'INTERDC_4_CALL_ERROR' , 'INTERDC_3_CALL_ERROR' , 'INTERDC_2_CALL_ERROR' , 'INTERDC_1_CALL_ERROR' , 'INTERDC_5_CALL_RICH_ERROR' , 'INTERDC_4_CALL_RICH_ERROR' , 'INTERDC_3_CALL_RICH_ERROR' , 'INTERDC_2_CALL_RICH_ERROR' , 'INTERDC_1_CALL_RICH_ERROR' ])) {
2022-02-23 11:45:18 +01:00
$res = true ;
2022-02-23 11:46:05 +01:00
//$res = $pdo->prepare('INSERT INTO rip VALUES (FROM_UNIXTIME(?));')->execute([time()]);
2020-07-25 20:01:48 +02:00
} elseif ( in_array ( $_REQUEST [ 'error' ], [ 'BOT_METHOD_INVALID' ])) {
if ( is_numeric ( $_REQUEST [ 'method' ])) {
require 'vendor/autoload.php' ;
$m = \danog\MadelineProto\Serialization :: deserialize ( 'tl.madeline' );
$method = $m -> API -> methods -> find_by_id ( $m -> pack_signed_int ( $_REQUEST [ 'method' ]))[ 'method' ];
if ( $method === false ) {
plsdie ( 'Could not find method by provided ID' );
}
} else {
$method = $_REQUEST [ 'method' ];
}
$res = $pdo -> prepare ( 'REPLACE INTO bot_method_invalid VALUES (?);' ) -> execute ([ $method ]);
} else {
if ( is_numeric ( $_REQUEST [ 'method' ])) {
require 'vendor/autoload.php' ;
$m = \danog\MadelineProto\Serialization :: deserialize ( 'tl.madeline' );
$method = $m -> API -> methods -> find_by_id ( $m -> pack_signed_int ( $_REQUEST [ 'method' ]))[ 'method' ];
if ( $method === false ) {
plsdie ( 'Could not find method by provided ID' );
}
} else {
$method = $_REQUEST [ 'method' ];
}
$res = $pdo -> prepare ( 'REPLACE INTO errors VALUES (?, ?, ?);' ) -> execute ([ $_REQUEST [ 'error' ], $method , $_REQUEST [ 'code' ]]);
$q = $pdo -> prepare ( 'SELECT description FROM error_descriptions WHERE error=?' );
$q -> execute ([ $_REQUEST [ 'error' ]]);
if ( $q -> rowCount ()) {
2022-02-11 21:09:55 +01:00
exit ( json_encode ([ 'ok' => true , 'result' => $q -> fetchColumn ()]));
2020-07-25 20:01:48 +02:00
} else {
plsdie ( 'No description' );
}
}
} catch ( \PDOException $e ) {
plsdie ( $e -> getMessage ());
} catch ( \danog\MadelineProto\Exception $e ) {
plsdie ( $e -> getMessage ());
} catch ( \danog\MadelineProto\TL\Exception $e ) {
plsdie ( $e -> getMessage ());
}
echo json_encode ([ 'ok' => $res ]);