MadelineProtoDocs/docs/UPDATES.md

193 lines
8.5 KiB
Markdown
Raw Normal View History

2018-04-01 13:19:25 +02:00
# Handling updates
Update handling can be done in different ways:
* [Event driven](#event-driven)
* [Event driven multithreaded](#event-driven-multithreaded)
* [Webhook](#webhook)
* [Webhook multithreaded](#webhook-multithreaded)
* [Long polling (getupdates)](#long-polling)
* [Callback](#callback)
* [Callback multithreaded](#callback-multithreaded)
IMPORTANT: Note that you should turn off update handling if you don't want to use it anymore because the default get_updates update handling stores updates in an array inside the MadelineProto object, without deleting old ones unless they are read using get_updates.
```php
$MadelineProto->settings['updates']['handle_updates'] = false;
```
## Event driven
```php
class EventHandler extends \danog\MadelineProto\EventHandler
{
public function __construct($MadelineProto)
{
parent::__construct($MadelineProto);
}
public function onAny($update)
{
\danog\MadelineProto\Logger::log("Received an update of type ".$update['_']);
}
public function onLoop()
{
\danog\MadelineProto\Logger::log("Working...");
}
public function onUpdateNewChannelMessage($update)
{
$this->onUpdateNewMessage($update);
}
public function onUpdateNewMessage($update)
{
if (isset($update['message']['out']) && $update['message']['out']) {
return;
}
$res = json_encode($update, JSON_PRETTY_PRINT);
if ($res == '') {
$res = var_export($update, true);
}
try {
$this->messages->sendMessage(['peer' => $update, 'message' => $res, 'reply_to_msg_id' => $update['message']['id'], 'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->messages->sendMessage(['peer' => '@danogentili', 'message' => $e->getCode().': '.$e->getMessage().PHP_EOL.$e->getTraceAsString()]);
}
try {
if (isset($update['message']['media']) && ($update['message']['media']['_'] == 'messageMediaPhoto' || $update['message']['media']['_'] == 'messageMediaDocument')) {
$time = microtime(true);
$file = $this->download_to_dir($update, '/tmp');
$this->messages->sendMessage(['peer' => $update, 'message' => 'Downloaded to '.$file.' in '.(microtime(true) - $time).' seconds', 'reply_to_msg_id' => $update['message']['id'], 'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
}
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->messages->sendMessage(['peer' => '@danogentili', 'message' => $e->getCode().': '.$e->getMessage().PHP_EOL.$e->getTraceAsString()]);
}
}
}
$MadelineProto = new \danog\MadelineProto\API('bot.madeline');
$MadelineProto->start();
$MadelineProto->setEventHandler('\EventHandler');
$MadelineProto->loop();
```
This will create an event handler class `EventHandler`, create a MadelineProto session, and set the event handler class to our newly created event handler.
When an [Update](https://docs.madelineproto.xyz/API_docs/types/Update.html) is received, the corresponding `onUpdateType` event handler method is called. To get a list of all possible update types, [click here](https://docs.madelineproto.xyz/API_docs/types/Update.html).
If such a method does not exist, the `onAny` event handler method is called.
If the `onAny` event handler method does not exist, the update is ignored.
The `onLoop` method, if it exists, will be called every time the update loop finishes one cycle, even if no update was received.
It is useful for scheduling actions.
To access the `$MadelineProto` instance inside of the event handler, simply access `$this`:
```php
$this->messages->sendMessage(['peer' => '@danogentili', 'message' => 'hi']);
```
If you intend to use your own constructor in the event handler, make sure to call the parent construtor with the only parameter provided to your constructor.
The update handling loop is started by the `$MadelineProto->loop()` method, and it will automatically restart the script if execution time runs out.
To break out of the loop just call `die();`
## Event driven multithreaded
To enable multithreaded update handling, pass `-1` to the `$MadelineProto->loop` method:
```php
$MadelineProto->loop(-1);
```
This way, each update will be managed in its own fork.
Note that multiprocessing is not the same as multithreading, and should be avoided unless lengthy operations are made in the update handler.
## Webhook
```php
$MadelineProto = new \danog\MadelineProto\API('bot.madeline');
$MadelineProto->start();
$MadelineProto->setWebhook('http://mybot.eu.org/madelinehook.php');
$MadelineProto->loop();
```
When an [Update](https://docs.madelineproto.xyz/API_docs/types/Update.html) is received, a POST request is made to the provided webhook URL, with json-encoded payload containing the Update. To get a list of all possible update types, [click here](https://docs.madelineproto.xyz/API_docs/types/Update.html).
The webhook can also respond with a JSON payload containing the name of a method to call and the arguments:
```json
{"method":"messages->sendMessage", "peer":"@danogentili", "message":"hi"}
```
The loop method will automatically restart the script if execution time runs out.
## Webhook multithreaded
To enable multithreaded update handling, pass `-1` to the `$MadelineProto->loop` method:
```php
$MadelineProto->loop(-1);
```
This way, each update could be managed faster.
## Long polling
```php
$MadelineProto = new \danog\MadelineProto\API('bot.madeline');
$MadelineProto->start();
while (true) {
$updates = $MadelineProto->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 0]); // Just like in the bot API, you can specify an offset, a limit and a timeout
\danog\MadelineProto\Logger::log($updates);
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
switch ($update['update']['_']) {
case 'updateNewMessage':
case 'updateNewChannelMessage':
if (isset($update['update']['message']['out']) && $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, '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()]);
}
}
}
}
```
The get_updates function accepts an array of options as the first parameter, and returns an array of updates (an array containing the update id and an object of type [Update](https://docs.madelineproto.xyz/API_docs/types/Update.html)).
## Callback
```php
$MadelineProto = new \danog\MadelineProto\API('bot.madeline');
$MadelineProto->start();
$MadelineProto->setCallback(function ($update) use ($MadelineProto) { \danog\MadelineProto\Logger::log("Received an update of type ".$update['_']); });
$MadelineProto->loop();
```
When an [Update](https://docs.madelineproto.xyz/API_docs/types/Update.html) is received, the provided callback function is called.
The update handling loop is started by the `$MadelineProto->loop()` method, and it will automatically restart the script if execution time runs out.
To break out of the loop just call `die();`
## Callback multithreaded
To enable multithreaded update handling, pass `-1` to the `$MadelineProto->loop` method:
```php
$MadelineProto->loop(-1);
```
This way, each update will be managed in its own fork.
Note that multiprocessing is not the same as multithreading, and should be avoided unless lengthy operations are made in the update handler.
<amp-form method="GET" target="_top" action="https://docs.madelineproto.xyz/docs/INSTALLATION.html"><input type="submit" value="Previous section" /></amp-form><amp-form action="https://docs.madelineproto.xyz/docs/SETTINGS.html" method="GET" target="_top"><input type="submit" value="Next section" /></amp-form>