1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-22 20:31:11 +01:00

Fetch entire update history when using getDialogs with bots

This commit is contained in:
Daniil Gentili 2023-01-29 16:48:18 +01:00
parent 3e0078e7ed
commit e2392db86c
4 changed files with 67 additions and 6 deletions

View File

@ -138,7 +138,7 @@ final class ProcessRunner extends RunnerAbstract
{
$executable = \strncasecmp(PHP_OS, 'WIN', 3) === 0 ? 'php.exe' : 'php';
$paths = \array_filter(\explode(PATH_SEPARATOR, \getenv('PATH')));
$paths = \array_filter(\explode(PATH_SEPARATOR, \getenv('PATH') ?: ''));
$paths[] = PHP_BINDIR;
$paths = \array_unique($paths);

View File

@ -687,6 +687,8 @@ final class MTProto implements TLCallback, LoggerGetter
'tmpDbPrefix',
// Misc caching
'botDialogsUpdatesState',
'cachedAllBotUsers',
'dialog_params',
'last_stored',
'qres',

View File

@ -495,6 +495,10 @@ trait UpdateHandler
} else {
$this->refreshPeerCache($update);
}
} catch (Exception $e) {
if ($e->getMessage() !== 'This peer is not present in the internal peer database') {
throw $e;
}
} catch (RPCErrorException $e) {
if ($e->rpc !== 'CHANNEL_PRIVATE') {
throw $e;
@ -569,11 +573,6 @@ trait UpdateHandler
$this->secretFeeders[$update['message']['chat_id']]->resume();
return;
}
/*
if ($update['_'] === 'updateEncryptedChatTyping') {
$update = ['_' => 'updateUserTyping', 'user_id' => $this->encrypted_chats[$update['chat_id']]['user_id'], 'action' => ['_' => 'sendMessageTypingAction']];
}
*/
if ($update['_'] === 'updateEncryption') {
switch ($update['chat']['_']) {
case 'encryptedChatRequested':

View File

@ -20,6 +20,7 @@ declare(strict_types=1);
namespace danog\MadelineProto\Wrappers;
use Amp\Sync\LocalMutex;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\Settings;
use Throwable;
@ -31,6 +32,13 @@ use Throwable;
*/
trait DialogHandler
{
private array $botDialogsUpdatesState = [
'qts' => 1,
'pts' => 1,
'date' => 1,
];
private bool $cachedAllBotUsers = false;
private ?LocalMutex $cachingAllBotUsers = null;
/**
* Get dialog peers.
*
@ -40,6 +48,58 @@ trait DialogHandler
public function getDialogs(bool $force = true): array
{
if ($this->authorization['user']['bot']) {
if (!$this->cachedAllBotUsers) {
$this->cachingAllBotUsers ??= new LocalMutex;
$lock = $this->cachingAllBotUsers->acquire();
try {
while (true) {
$this->logger($this->botDialogsUpdatesState);
$result = $this->methodCallAsyncRead(
'updates.getDifference',
[
...$this->botDialogsUpdatesState,
'pts_total_limit' => 2147483647
]
);
switch ($result['_']) {
case 'updates.differenceEmpty':
break 2;
case 'updates.difference':
$this->botDialogsUpdatesState = $result['state'];
break;
case 'updates.differenceSlice':
$this->botDialogsUpdatesState = $result['intermediate_state'];
break;
case 'updates.differenceTooLong':
// Binary search for working PTS
$bottom = $this->botDialogsUpdatesState['pts'];
$top = $result['pts'];
$state = $this->botDialogsUpdatesState;
$state['pts_total_limit'] = 2147483647;
while ($bottom <= $top) {
$state['pts'] = ($bottom+$top)>>1;
$result = $this->methodCallAsyncRead(
'updates.getDifference',
$state
)['_'];
$this->logger("$bottom, {$state['pts']}, $top");
$this->logger($result);
if ($result === 'updates.differenceTooLong') {
$bottom = $state['pts']+1;
} else {
$top = $state['pts']-1;
}
}
$this->botDialogsUpdatesState['pts'] = $bottom;
$this->logger("Found PTS $bottom");
break;
}
}
$this->cachedAllBotUsers = true;
} finally {
$lock->release();
}
}
$res = [];
foreach ($this->chats as $chat) {
try {