Written first MadelineProto bot, fixed update management, fixed bugs

This commit is contained in:
Daniil Gentili 2017-01-04 12:22:03 +00:00
parent cc7c983929
commit f54fb0b6b3
10 changed files with 79 additions and 46 deletions

View File

@ -209,10 +209,10 @@ $offset = 0;
while (true) {
$updates = $MadelineProto->API->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 1]); // Just like in the bot API, you can specify an offset, a limit and a timeout
foreach ($updates as $update) {
$offset = $update['update_id'] // Just like in the bot API, the offset must be set to the last update_id
$offset = $update['update_id']; // Just like in the bot API, the offset must be set to the last update_id
// Parse $update['update'], that is an object of type Update
}
var_dump($update);
var_dump($updates);
}
array(3) {

28
bot.php Normal file
View File

@ -0,0 +1,28 @@
<?php
require 'vendor/autoload.php';
$settings = [];
$MadelineProto = \danog\MadelineProto\Serialization::deserialize('bot.madeline');
if (file_exists('token.php') && $MadelineProto === false) {
include_once 'token.php';
$MadelineProto = new \danog\MadelineProto\API($settings);
$authorization = $MadelineProto->bot_login($token);
\danog\MadelineProto\Logger::log($authorization);
}
$offset = 0;
while (true) {
$updates = $MadelineProto->API->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 0]); // Just like in the bot API, you can specify an offset, a limit and a timeout
foreach ($updates as $update) {
$offset = $update['update_id'] + 1; // Just like in the bot API, the offset must be set to the last update_id
var_dump($update);
switch ($update['update']['_']) {
case 'updateNewMessage':
if ($update['update']['message']['out']) continue;
$res = json_encode($update, JSON_PRETTY_PRINT);
if ($res == '') $res =var_export($update, true);
try { $MadelineProto->messages->sendMessage(['peer' => $update['update']['message']['from_id'], 'message' => $res, 'reply_to_msg_id' => $update['update']['message']['id'], 'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json', ]]]); } catch (\danog\MadelineProto\RPCErrorException $e) { $MadelineProto->messages->sendMessage(['peer' => '@danogentili', 'message' => $e->getCode().': '.$e->getMessage().PHP_EOL.$e->getTraceAsString()]); }
}
}
echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('bot.madeline', $MadelineProto).' bytes'.PHP_EOL;
}

View File

@ -213,10 +213,10 @@ $offset = 0;
while (true) {
$updates = $MadelineProto->API->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 1]); // Just like in the bot API, you can specify an offset, a limit and a timeout
foreach ($updates as $update) {
$offset = $update['update_id'] // Just like in the bot API, the offset must be set to the last update_id
$offset = $update['update_id']; // Just like in the bot API, the offset must be set to the last update_id
// Parse $update['update'], that is an object of type Update
}
var_dump($update);
var_dump($updates);
}
array(3) {

17
id.php
View File

@ -11,21 +11,21 @@ If not, see <http://www.gnu.org/licenses/>.
*/
require 'vendor/autoload.php';
require '../db_id.php';
//require '../db:id.php';
$select = $pdo->prepare('SELECT * FROM ul');
$select->execute();
$pdores = $select->fetchAll(PDO::FETCH_ASSOC);
//$select = $pdo->prepare('SELECT * FROM ul');
//$select->execute();
//$pdores = $select->fetchAll(PDO::FETCH_ASSOC);
function foreach_offset_length($string)
{
$res = [];
$strlen = strlen($string);
for ($offset = 0; $offset < strlen($string); $offset++) {
for ($length = 1; $length > 0; $length--) {
for ($length = $strlen - $offset; $length > 0; $length--) {
$s = substr($string, $offset, $length);
//$number = (string) (new \phpseclib\Math\BigInteger(strrev($s), 256));
$number = ord($s);
$number = (string) (new \phpseclib\Math\BigInteger(strrev($s), 256));
//$number = ord($s);
$res[] = ['number' => $number, 'offset' => $offset, 'length' => $length];
}
}
@ -33,6 +33,7 @@ function foreach_offset_length($string)
return $res;
}
$res = [];
$pdores = [['file_id' => 'AwADBAADiQEAAo_aCgYAAc-fglzxcY0C']];
foreach ($pdores as $r) {
$base256 = base64url_decode($r['file_id']);
$res = foreach_offset_length($base256);
@ -46,7 +47,7 @@ foreach ($pdores as $r) {
}
}
}
var_dump($same);
var_dump($res);
function base64url_decode($data)
{
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));

View File

@ -63,8 +63,8 @@ description: '.$this->settings['description'].'
\danog\MadelineProto\Logger::log('Generating methods documentation...');
foreach ($this->methods->method as $key => $method) {
$method = str_replace('.', '_', $method);
foreach ($this->methods->method as $key => $rmethod) {
$method = str_replace('.', '_', $rmethod);
$real_method = str_replace('.', '->', $method);
$type = str_replace(['.', '<', '>'], ['_', '_of_', ''], $this->methods->type[$key]);
$real_type = preg_replace('/.*_of_/', '', $type);

View File

@ -198,7 +198,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
'outgoing' => 1000,
],
'updates' => [
'updates_array_limit' => 1000, // How big should be the array containing the updates processed with the default example_update_handler callback
'handle_updates' => true, // Should I handle updates?
'callback' => [$this, 'get_updates_update_handler'], // A callable function that will be called every time an update is received, must accept an array (for the update) as the only parameter
],
];

View File

@ -33,7 +33,7 @@ trait AckHandler
{
// I let the server know that I received its message
if (!isset($this->datacenter->incoming_messages[$message_id])) {
\danog\MadelineProto\Logger::log("WARNING: Couldn't find message id ".$message_id.' in the array of outgoing messages. Maybe try to increase its size?');
\danog\MadelineProto\Logger::log("WARNING: Couldn't find message id ".$message_id.' in the array of incomgoing messages. Maybe try to increase its size?');
//throw new \danog\MadelineProto\Exception("Couldn't find message id ".$message_id.' in the array of incoming message ids. Maybe try to increase its size?');
}
if ($this->datacenter->temp_auth_key['id'] === null || $this->datacenter->temp_auth_key['id'] == $this->string2bin('\x00\x00\x00\x00\x00\x00\x00\x00') || (isset($this->datacenter->incoming_messages[$message_id]['ack']) && $this->datacenter->incoming_messages[$message_id]['ack'])) {

View File

@ -37,10 +37,11 @@ trait MsgIdHandler
if ($new_message_id <= end($keys)) {
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is lower than or equal than the current limit ('.end($keys).').', 1);
}
$this->datacenter->outgoing_messages[$new_message_id] = [];
if (count($this->datacenter->outgoing_messages) > $this->settings['msg_array_limit']['outgoing']) {
array_shift($this->datacenter->outgoing_messages);
reset($this->datacenter->outgoing_messages);
unset($this->datacenter->outgoing_messages[key($this->datacenter->outgoing_messages)]);
}
$this->datacenter->outgoing_messages[$new_message_id] = [];
} else {
if ($new_message_id % 4 != 1 && $new_message_id % 4 != 3) {
throw new \danog\MadelineProto\Exception('message id mod 4 != 1 or 3');
@ -59,10 +60,11 @@ trait MsgIdHandler
}
}
}
$this->datacenter->incoming_messages[$new_message_id] = [];
if (count($this->datacenter->incoming_messages) > $this->settings['msg_array_limit']['incoming']) {
array_shift($this->datacenter->incoming_messages);
reset($this->datacenter->outgoing_messages);
unset($this->datacenter->outgoing_messages[key($this->datacenter->outgoing_messages)]);
}
$this->datacenter->incoming_messages[$new_message_id] = [];
ksort($this->datacenter->incoming_messages);
}
}

View File

@ -82,8 +82,8 @@ trait ResponseHandler
if (isset($response['result']['users'])) {
$this->add_users($response['result']['users']);
}
if (isset($response['result']['chats'])) {
$this->add_chats($response['result']['chats']);
if (isset($response['result']['_']) && $this->constructors->find_by_predicate($response['result']['_'])['type'] == 'Update') {
$this->handle_update($response['result']);
}
switch ($response['_']) {
case 'msgs_ack':
@ -255,6 +255,7 @@ trait ResponseHandler
public function handle_updates($updates)
{
if (!$this->settings['updates']['handle_updates']) return;
\danog\MadelineProto\Logger::log('Parsing updates received via the socket...');
if ($this->getting_state) {
\danog\MadelineProto\Logger::log('Getting state, handle later');

View File

@ -25,35 +25,34 @@ trait UpdateHandler
public function get_updates_update_handler($update)
{
if (count($this->updates) > $this->settings['updates']['updates_array_limit']) {
array_shift($this->updates);
}
$this->updates[$this->updates_key++] = $update;
//\danog\MadelineProto\Logger::log('Stored ', $update);
}
public function get_updates($params = [])
{
$time = microtime(true);
$this->force_get_updates_difference();
if (empty($this->updates)) {
return [];
}
$default_params = ['offset' => array_keys($this->updates)[0], 'limit' => null, 'timeout' => 0];
$default_params = ['offset' => 0, 'limit' => null, 'timeout' => 0];
foreach ($default_params as $key => $default) {
if (!isset($params[$key])) {
$params[$key] = $default;
}
}
$time = microtime(true);
$params['timeout'] = (int) ($params['timeout'] - (microtime(true) - $time));
sleep($params['timeout'] > 0 ? $params['timeout'] : 0);
$result = array_slice($this->updates, $params['offset'], $params['limit'], true);
$updates = [];
foreach ($result as $key => $value) {
$updates[] = ['update_id' => $key, 'update' => $value];
unset($this->updates[$key]);
$params['timeout'] = (int) ($params['timeout']*1000000 - (microtime(true) - $time));
usleep($params['timeout'] > 0 ? $params['timeout'] : 0);
if (empty($this->updates)) {
return [];
}
if ($params['offset'] < 0) $params['offset'] = array_reverse(array_keys($this->updates))[abs($params['offset'])-1];
$updates = [];
foreach ($this->updates as $key => $value) {
if ($params['offset'] > $key) {
unset($this->updates[$key]);
} else if ($params['limit'] == null || count($updates) < $params['limit']) {
$updates[] = ['update_id' => $key, 'update' => $value];
}
}
return $updates;
}
@ -204,13 +203,13 @@ trait UpdateHandler
} else {
$cur_state = &$this->get_channel_state($channel_id, (isset($update['pts']) ? $update['pts'] : 0) - (isset($update['pts_count']) ? $update['pts_count'] : 0));
}
/*
if ($cur_state['sync_loading']) {
\danog\MadelineProto\Logger::log('Sync loading, not handling update');
return false;
}
*/
switch ($update['_']) {
case 'updateChannelTooLong':
$this->get_channel_difference($channel_id);
@ -220,7 +219,7 @@ trait UpdateHandler
case 'updateEditMessage':
case 'updateNewChannelMessage':
case 'updateEditChannelMessage':
$message = $update['message'];
$message = &$update['message'];
if ((isset($message['from_id']) && !$this->peer_isset($message['from_id'])) ||
!$this->peer_isset($message['to_id']) ||
(isset($message['via_bot_id']) && !$this->peer_isset($message['via_bot_id'])) ||
@ -236,6 +235,7 @@ trait UpdateHandler
return false;
}
if ($message['from_id'] == $this->datacenter->authorization['user']['id']) { $message['out'] = true; }
break;
default:
if ($channel_id !== false && !$this->peer_isset('channel#'.$channel_id)) {
@ -267,7 +267,7 @@ trait UpdateHandler
$cur_state['pts'] = $update['pts'];
$pop_pts = true;
} elseif (isset($update['pts_count']) && $update['pts_count']) {
\danog\MadelineProto\Logger::log('Duplicate update. current pts: '.$cur_state['pts'].' + pts count: '.(isset($update['pts_count']) ? $update['pts_count'] : 0).' = new pts: '.$new_pts.'. update pts: '.$update['pts'].' <= current pts '.$cur_state['pts'].', channel id: '.$channel_id);
\danog\MadelineProto\Logger::log('Duplicate update. current pts: '.$cur_state['pts'].' + pts count: '.(isset($update['pts_count']) ? $update['pts_count'] : 0).' = new pts: '.$new_pts.'. update pts: '.$update['pts'].' <= current pts '.$cur_state['pts'].', channel id: '.$channel_id, $update);
return false;
}
@ -359,7 +359,7 @@ trait UpdateHandler
public function handle_multiple_update($updates, $options = [], $channel = false)
{
if ($channel == false) {
if ($channel === false) {
foreach ($updates as $update) {
switch ($update['_']) {
case 'updateChannelTooLong':
@ -368,11 +368,11 @@ trait UpdateHandler
$this->handle_update($update, $options);
continue 2;
}
$this->save_update($update);
$this->handle_update($update);
}
} else {
foreach ($updates as $update) {
$this->save_update($update);
$this->handle_update($update);
}
}
}
@ -380,12 +380,13 @@ trait UpdateHandler
public function handle_update_messages($messages, $channel = false)
{
foreach ($messages as $message) {
$this->save_update(['_' => $channel == false ? 'updateNewMessage' : 'updateNewChannelMessage', 'message' => $message, 'pts' => $channel == false ? $this->get_update_state()['pts'] : $this->get_channel_state($channel)['pts'], 'pts_count' => 0]);
$this->handle_update(['_' => $channel == false ? 'updateNewMessage' : 'updateNewChannelMessage', 'message' => $message, 'pts' => $channel == false ? $this->get_update_state()['pts'] : $this->get_channel_state($channel)['pts'], 'pts_count' => 0]);
}
}
public function save_update($update)
{
if (!$this->settings['updates']['handle_updates']) return;
\danog\MadelineProto\Logger::log('Saving an update of type '.$update['_'].'...');
$this->settings['updates']['callback']($update);
}