Skip to content

Commit

Permalink
Make getID work with usernames, allow calling restart() and stop() fr…
Browse files Browse the repository at this point in the history
…om outside the event handler
  • Loading branch information
danog committed Apr 22, 2023
1 parent e628d7c commit 56a9af5
Show file tree
Hide file tree
Showing 16 changed files with 136 additions and 93 deletions.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ The following open source projects were created using MadelineProto: you can dir

<!-- * [magnaluna webradio](https://magna.madelineproto.xyz) - Multifeatured Telegram VoIP webradio -->
* [TelegramApiServer](https://github.com/xtrime-ru/TelegramApiServer) - Fast, simple, async php telegram api server: an HTTP JSON API for MadelineProto!
* [`downloadRenameBot.php`](https://github.com/danog/MadelineProto/blob/master/examples/downloadRenameBot.php) - Download files by URL and rename Telegram files using this async parallelized bot!
* [`secret_bot.php`](https://github.com/danog/MadelineProto/blob/master/examples/secret_bot.php) - Secret chat bot!
* [`pipesbot.php`](https://github.com/danog/MadelineProto/blob/master/examples/pipesbot.php) - Creating inline bots and using other inline bots via a userbot!
* [`bot.php`](https://github.com/danog/MadelineProto/blob/master/examples/bot.php) - Examples for sending normal messages, downloading any media!
* [`downloadRenameBot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/downloadRenameBot.php) - Download files by URL and rename Telegram files using this async parallelized bot!
* [`secret_bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/secret_bot.php) - Secret chat bot!
* [`pipesbot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/pipesbot.php) - Creating inline bots and using other inline bots via a userbot!
* [`bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/bot.php) - Examples for sending normal messages, downloading any media!

Want to add your own open-source project to this list? [Click here!](https://docs.madelineproto.xyz/FOSS.html)

Expand All @@ -84,7 +84,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* [Simple](https://docs.madelineproto.xyz/docs/INSTALLATION.html#simple)
* [Composer from existing project](https://docs.madelineproto.xyz/docs/INSTALLATION.html#composer-from-existing-project)
* [Composer from scratch](https://docs.madelineproto.xyz/docs/INSTALLATION.html#composer-from-scratch)
* [Handling updates (new messages)](https://docs.madelineproto.xyz/docs/UPDATES.html)
* [Handling updates (new messages & other events)](https://docs.madelineproto.xyz/docs/UPDATES.html)
* [Async Event driven](https://docs.madelineproto.xyz/docs/UPDATES.html#async-event-driven)
* [Built-in database driver](https://docs.madelineproto.xyz/docs/UPDATES.html#built-in-database-driver)
* [Self-restart on webhosts](https://docs.madelineproto.xyz/docs/UPDATES.html#self-restart-on-webhosts)
Expand Down Expand Up @@ -185,7 +185,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* [Async readline](https://docs.madelineproto.xyz/docs/ASYNC.html#async-readline-does-not-block-the-main-thread)
* [Async echo](https://docs.madelineproto.xyz/docs/ASYNC.html#async-echo-does-not-block-the-main-thread)
* [MadelineProto HTTP client](https://docs.madelineproto.xyz/docs/ASYNC.html#madelineproto-http-client)
* [Async forking](https://docs.madelineproto.xyz/docs/ASYNC.html#async-forking-does-green-thread-forking)
* [Async forking](https://docs.madelineproto.xyz/docs/ASYNC.html#async-forking-does-async-green-thread-forking)
* [Async flock](https://docs.madelineproto.xyz/docs/ASYNC.html#async-flock)
* [MadelineProto async loop APIs](https://docs.madelineproto.xyz/docs/ASYNC.html#async-loop-apis)
* [Using methods](https://docs.madelineproto.xyz/docs/USING_METHODS.html)
Expand Down Expand Up @@ -266,7 +266,6 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.createChat.html" name="messages.createChat">Creates a new chat: messages.createChat</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.deleteChannel.html" name="channels.deleteChannel">Delete a channel/supergroup: channels.deleteChannel</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.deleteChat.html" name="messages.deleteChat">Delete a chat: messages.deleteChat</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/folders.deleteFolder.html" name="folders.deleteFolder">Delete a peer folder: folders.deleteFolder</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.deleteExportedChatInvite.html" name="messages.deleteExportedChatInvite">Delete a chat invite: messages.deleteExportedChatInvite</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.resetWallPapers.html" name="account.resetWallPapers">Delete all installed wallpapers, reverting to the default wallpaper set: account.resetWallPapers</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.deleteParticipantHistory.html" name="channels.deleteParticipantHistory">Delete all messages sent by a specific participant of a given supergroup: channels.deleteParticipantHistory</a>
Expand Down
2 changes: 1 addition & 1 deletion docs
Submodule docs updated 69 files
+3 −2 docs/API_docs/constructors/auth.sentCodeTypeEmailCode.md
+30 −0 docs/API_docs/constructors/bots.botInfo.md
+2 −1 docs/API_docs/constructors/channelAdminLogEventActionParticipantJoinByInvite.md
+2 −1 docs/API_docs/constructors/chatInviteImporter.md
+32 −0 docs/API_docs/constructors/chatlists.chatlistInvite.md
+32 −0 docs/API_docs/constructors/chatlists.chatlistInviteAlready.md
+30 −0 docs/API_docs/constructors/chatlists.chatlistUpdates.md
+29 −0 docs/API_docs/constructors/chatlists.exportedChatlistInvite.md
+30 −0 docs/API_docs/constructors/chatlists.exportedInvites.md
+32 −0 docs/API_docs/constructors/dialogFilterChatlist.md
+29 −0 docs/API_docs/constructors/exportedChatlistInvite.md
+44 −8 docs/API_docs/constructors/index.md
+22 −0 docs/API_docs/constructors/inlineQueryPeerTypeBotPM.md
+27 −0 docs/API_docs/constructors/inputChatlistDialogFilter.md
+2 −1 docs/API_docs/constructors/keyboardButtonSwitchInline.md
+3 −1 docs/API_docs/constructors/messageActionGiftPremium.md
+27 −0 docs/API_docs/constructors/messageActionSetChatWallPaper.md
+27 −0 docs/API_docs/constructors/messageActionSetSameChatWallPaper.md
+2 −1 docs/API_docs/constructors/updateChannelParticipant.md
+2 −1 docs/API_docs/constructors/user.md
+2 −1 docs/API_docs/constructors/userFull.md
+1 −1 docs/API_docs/index.md
+2 −1 docs/API_docs/methods/account.uploadWallPaper.md
+65 −9 docs/API_docs/methods/api_index.md
+41 −0 docs/API_docs/methods/auth.resetLoginEmail.md
+3 −2 docs/API_docs/methods/bots.getBotInfo.md
+41 −0 docs/API_docs/methods/bots.reorderUsernames.md
+3 −1 docs/API_docs/methods/bots.setBotInfo.md
+42 −0 docs/API_docs/methods/bots.toggleUsername.md
+40 −0 docs/API_docs/methods/chatlists.checkChatlistInvite.md
+41 −0 docs/API_docs/methods/chatlists.deleteExportedInvite.md
+43 −0 docs/API_docs/methods/chatlists.editExportedInvite.md
+42 −0 docs/API_docs/methods/chatlists.exportChatlistInvite.md
+40 −0 docs/API_docs/methods/chatlists.getChatlistUpdates.md
+40 −0 docs/API_docs/methods/chatlists.getExportedInvites.md
+40 −0 docs/API_docs/methods/chatlists.getLeaveChatlistSuggestions.md
+40 −0 docs/API_docs/methods/chatlists.hideChatlistUpdates.md
+41 −0 docs/API_docs/methods/chatlists.joinChatlistInvite.md
+41 −0 docs/API_docs/methods/chatlists.joinChatlistUpdates.md
+41 −0 docs/API_docs/methods/chatlists.leaveChatlist.md
+0 −42 docs/API_docs/methods/folders.deleteFolder.md
+0 −2 docs/API_docs/methods/index.md
+43 −0 docs/API_docs/methods/messages.setChatWallPaper.md
+2 −1 docs/API_docs/methods/photos.updateProfilePhoto.md
+2 −1 docs/API_docs/methods/photos.uploadProfilePhoto.md
+2 −0 docs/API_docs/types/DialogFilter.md
+23 −0 docs/API_docs/types/ExportedChatlistInvite.md
+2 −0 docs/API_docs/types/InlineQueryPeerType.md
+21 −0 docs/API_docs/types/InputChatlist.md
+4 −0 docs/API_docs/types/MessageAction.md
+2 −0 docs/API_docs/types/Peer.md
+7 −1 docs/API_docs/types/Updates.md
+2 −0 docs/API_docs/types/auth.SentCode.md
+24 −0 docs/API_docs/types/bots.BotInfo.md
+26 −0 docs/API_docs/types/chatlists.ChatlistInvite.md
+24 −0 docs/API_docs/types/chatlists.ChatlistUpdates.md
+24 −0 docs/API_docs/types/chatlists.ExportedChatlistInvite.md
+24 −0 docs/API_docs/types/chatlists.ExportedInvites.md
+14 −2 docs/API_docs/types/index.md
+4 −5 docs/docs/CONTRIB.md
+1 −1 docs/docs/DATABASE.md
+1 −1 docs/docs/FILES.md
+2 −2 docs/docs/PROXY.md
+2 −2 docs/docs/REQUIREMENTS.md
+1 −1 docs/docs/SECRET_CHATS.md
+117 −30 docs/docs/UPDATES.md
+9 −9 docs/docs/UPDATES_INTERNAL.md
+4 −4 docs/docs/USING_METHODS.md
+6 −7 docs/index.md
74 changes: 45 additions & 29 deletions examples/bot.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env php
<?php declare(strict_types=1);
/**
* Example bot.
Expand Down Expand Up @@ -26,34 +25,35 @@
use danog\MadelineProto\Settings\Database\Postgres;
use danog\MadelineProto\Settings\Database\Redis;

/*
* Various ways to load MadelineProto
*/
// If a stable version of MadelineProto was installed via composer, load composer autoloader
if (file_exists('vendor/autoload.php')) {
include 'vendor/autoload.php';
require_once 'vendor/autoload.php';
} else {
// Otherwise download an alpha version of MadelineProto via madeline.php
if (!file_exists('madeline.php')) {
copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
}
/**
* @psalm-suppress MissingFile
*/
include 'madeline.php';
require_once 'madeline.php';
}

/**
* Event handler class.
*/
class MyEventHandler extends EventHandler
class SecretHandler extends EventHandler
{
/**
* @var int|string Username or ID of bot admin
*/
const ADMIN = "danogentili"; // Change this
const ADMIN = "danogentili"; // !!! Change this to your username !!!

/**
* List of properties automatically stored in database (MySQL, Postgres, redis or memory).
*
* Note that **all** properties will be stored in the database, regardless of whether they're specified here.
* The only difference is that properties *not* specified in this array will also always have a full copy in RAM.
*
* Also, properties specified in this array are NOT thread-safe, meaning you should also use a synchronization primitive
* from https://github.com/amphp/sync/ to use them in a thread-safe manner.
*
* @see https://docs.madelineproto.xyz/docs/DATABASE.html
*/
protected static array $dbProperties = [
Expand All @@ -70,6 +70,8 @@ class MyEventHandler extends EventHandler
*/
protected array $notifiedChats = [];

private int $adminId;

/**
* Get peer(s) where to report errors.
*
Expand All @@ -86,6 +88,7 @@ public function onStart(): void
{
$this->logger("The bot was started!");
$this->logger($this->getFullInfo('MadelineProto'));
$this->adminId = $this->getId(self::ADMIN);
}
/**
* Handle updates from supergroups and channels.
Expand All @@ -110,9 +113,14 @@ public function onUpdateNewMessage(array $update): void

$this->logger($update);

// Chat id
// Chat ID
$id = $this->getId($update);

// Sender ID, not always present
$from_id = isset($update['message']['from_id'])
? $this->getId($update['message']['from_id'])
: null;

// In this example code, send the "This userbot is powered by MadelineProto!" message only once per chat.
// Ignore all further messages coming from this chat.
if (!isset($this->notifiedChats[$id])) {
Expand All @@ -124,25 +132,27 @@ public function onUpdateNewMessage(array $update): void
reply_to_msg_id: $update['message']['id'] ?? null,
parse_mode: 'Markdown'
);
}

if (isset($update['message']['media'])
&& !in_array($update['message']['media']['_'], [
'messageMediaGame',
'messageMediaWebPage',
'messageMediaPoll'
])
) {
$this->messages->sendMedia(
peer: $update,
message: $update['message']['message'],
media: $update
);
}
// If the message is a /restart command from an admin, restart to reload changes to the event handler code.
if (($update['message']['message'] ?? '') === '/restart'
&& $from_id === $this->adminId
) {
// Make sure to run in a bash while loop when running via CLI to allow self-restarts.
$this->restart();
}

// Remove the following example code when running your bot

// Test MadelineProto's built-in database driver, which automatically maps to MySQL/PostgreSQL/Redis
// properties mentioned in the MyEventHandler::$dbProperties property!

// Note that **all** properties will be stored in the database, regardless of whether they're specified in $dbProperties
// The only difference is that properties *not* specified in $dbProperties will also always have a full copy in RAM.
//
// Also, properties specified in $dbProperties are NOT thread-safe, meaning you should also use a synchronization primitive
// from https://github.com/amphp/sync/ to use them in a thread-safe manner.
//
// Can be anything serializable: an array, an int, an object, ...
$myData = [];

Expand All @@ -162,6 +172,10 @@ public function onUpdateNewMessage(array $update): void
$this->logger($value);
}
}

// 100+ other types of onUpdate... method types are available, see https://docs.madelineproto.xyz/API_docs/types/Update.html for the full list.

// You can also use onAny to catch all update types (only for debugging)
}

$settings = new Settings;
Expand All @@ -172,6 +186,8 @@ public function onUpdateNewMessage(array $update): void
// $settings->setDb((new Postgres)->setDatabase('MadelineProto')->setUsername('daniil')->setPassword('pony'));
// $settings->setDb((new Mysql)->setDatabase('MadelineProto')->setUsername('daniil')->setPassword('pony'));

// Reduce boilerplate with new wrapper method.
// Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
MyEventHandler::startAndLoop('uwu.madeline', $settings);
// For users or bots
SecretHandler::startAndLoop('bot.madeline', $settings);

// For bots only
SecretHandler::startAndLoopBot('bot.madeline', 'bot token', $settings);
2 changes: 1 addition & 1 deletion schemas
Submodule schemas updated 1 files
+2,078 −0 TL_telegram_v158.tl
14 changes: 0 additions & 14 deletions src/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,6 @@ final public static function startAndLoopBot(string $session, string $token, Set
$API->botLogin($token);
$API->startAndLoopInternal(static::class);
}
/**
* Stop event handler.
*/
public function stop(): void
{
$this->wrapper->getAPI()->stop();
}
/**
* Restart event handler.
*/
public function restart(): void
{
$this->wrapper->getAPI()->restart();
}
protected function reconnectFull(): bool
{
return true;
Expand Down
27 changes: 18 additions & 9 deletions src/InternalDoc.php
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,11 @@ public function getHint(): string
return $this->wrapper->getAPI()->getHint();
}
/**
* Get bot API ID from peer object.
* Get the bot API ID of a peer.
*
* @param mixed $id Peer
*/
public function getId(mixed $id): ?int
public function getId(mixed $id): int
{
return $this->wrapper->getAPI()->getId($id);
}
Expand Down Expand Up @@ -1028,13 +1028,6 @@ public static function inflateStripped(string $stripped): string
{
return \danog\MadelineProto\Tools::inflateStripped($stripped);
}
/**
* Initialize self-restart hack.
*/
public function initSelfRestart(): void
{
$this->wrapper->getAPI()->initSelfRestart();
}
/**
* Whether this is altervista.
*/
Expand Down Expand Up @@ -1095,6 +1088,8 @@ public function logger(mixed $param, int $level = \danog\MadelineProto\Logger::N
/**
* Start MadelineProto's update handling loop, or run the provided async callable.
*
* @deprecated Not needed anymore with amp v3
*
* @param callable|null $callback Async callable to run
*/
public function loop(?callable $callback = null)
Expand Down Expand Up @@ -1306,6 +1301,13 @@ public function resetUpdateState(): void
{
$this->wrapper->getAPI()->resetUpdateState();
}
/**
* Restart update loop.
*/
public function restart(): void
{
$this->wrapper->getAPI()->restart();
}
/**
* Rethrow exception into event loop.
*/
Expand Down Expand Up @@ -1422,6 +1424,13 @@ public function start()
{
return $this->wrapper->getAPI()->start();
}
/**
* Stop update loop.
*/
public function stop(): void
{
$this->wrapper->getAPI()->stop();
}
/**
* Subscribe to event handler updates for a channel/supergroup we're not a member of.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Loop/Update/FeedLoop.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public function feedSingle(array $update)
) {
$log = '';
if ($from) {
$from_id = $this->API->getId($update['message']['from_id']);
$from_id = $this->API->getIdInternal($update['message']['from_id']);
$log .= "from_id {$from_id}, ";
}
if ($to) {
Expand Down
2 changes: 1 addition & 1 deletion src/MTProtoSession/ResponseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ private function handleResponse(IncomingMessage $message, ?string $requestId = n
$trimmed = $body;
if (isset($trimmed['peer'])) {
try {
$trimmed['peer'] = \is_string($body['peer']) ? $body['peer'] : $this->API->getId($body['peer']);
$trimmed['peer'] = \is_string($body['peer']) ? $body['peer'] : $this->API->getIdInternal($body['peer']);
} catch (Throwable $e) {
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/MTProtoTools/MinDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public function addPeer(array $location): bool
switch ($location['_']) {
case 'messageFwdHeader':
if (isset($location['from_id'])) {
$peers[$this->API->getId($location['from_id'])] = true;
$peers[$this->API->getIdInternal($location['from_id'])] = true;
}
if (isset($location['channel_id'])) {
$peers[$this->API->toSupergroup($location['channel_id'])] = true;
Expand All @@ -151,13 +151,13 @@ public function addPeer(array $location): bool
}
break;
case 'message':
$peers[$this->API->getId($location['peer_id'])] = true;
$peers[$this->API->getIdInternal($location['peer_id'])] = true;
if (isset($location['from_id'])) {
$peers[$this->API->getId($location['from_id'])] = true;
$peers[$this->API->getIdInternal($location['from_id'])] = true;
}
break;
default:
$peers[$this->API->getId($location)] = true;
$peers[$this->API->getIdInternal($location)] = true;
}
$this->API->logger->logger("Caching peer location info from location from {$location['_']}", Logger::ULTRA_VERBOSE);
$key = \count($this->cache) - 1;
Expand All @@ -181,7 +181,7 @@ public function addOrigin(array $data = []): void
switch ($data['_']) {
case 'message':
case 'messageService':
$origin['peer'] = $this->API->getId($data);
$origin['peer'] = $this->API->getIdInternal($data);
$origin['msg_id'] = $data['id'];
break;
default:
Expand All @@ -200,7 +200,7 @@ public function populateFrom(array $object)
if (!($object['min'] ?? false)) {
return $object;
}
$id = $this->API->getId($object);
$id = $this->API->getIdInternal($object);
$dbObject = $this->db[$id];
if ($dbObject) {
$new = \array_merge($object, $dbObject);
Expand Down
Loading

0 comments on commit 56a9af5

Please sign in to comment.