-
Notifications
You must be signed in to change notification settings - Fork 172
Upgrading from v2 to v3
v3 is a major change in direction for this API.
The TgLog class did change the order it receives the parameters. It used to be "Bot token" - "Logger" - "Request handler", and now it is "Bot token" - "Request handler" - "Logger".
New in this release are so-called Request Handlers. A Request Handler is, simply said, a class that handles the talking to Telegram.
It is now required to pass a Request Handler to the TgLog
object when constructing it:
<?php
// Old style:
$tgLog = new \unreal4u\TelegramAPI\TgLog(BOT_TOKEN);
// New style:
$loop = \React\EventLoop\Factory::create();
$handler = new \unreal4u\TelegramAPI\HttpClientRequestHandler($loop);
$tgLog = new \unreal4u\TelegramAPI\TgLog(BOT_TOKEN, $handler);
The added benefit of this structure is that it will be possible to swap out a backend for another backend. For example, the new non-blocking React\HttpClient backend may be swapped out for a blocking backend, powered by a different client, such as the old Guzzle client.
Version 3 of the API will work in an async manner, meaning that a request will not block other work going on. While PHP is not async by design, it can be emulated by doing parts of the work on every tick. It uses ReactPHP components like its event loop and HttpClient to achieve this.
While at first a simple call to TgLog::performApiRequest
was sufficient to get the appropriate Telegram reply object,
it will now return a React\Promise\PromiseInterface
(more on promises here),
which you can pass a pair of callbacks (onFulfilled
and onRejected
respectively). Consider the following code for an
example (note that this code will NOT execute):
<?php
declare(strict_types = 1);
use unreal4u\TelegramAPI\InternalFunctionality\TelegramDocument;
use unreal4u\TelegramAPI\Telegram\Methods\GetFile;
use unreal4u\TelegramAPI\Telegram\Types\File;
use unreal4u\TelegramAPI\TgLog;
// ----- CHANGE THIS CODE: -----
$tgLog = new TgLog(BOT_TOKEN);
// ----- TO THIS: -----
$loop = \React\EventLoop\Factory::create();
$handler = new \unreal4u\TelegramAPI\HttpClientRequestHandler($loop);
$tgLog = new TgLog(BOT_TOKEN, $handler);
$getFile = new GetFile();
$getFile->file_id = A_FILE_ID;
// ----- THE FOLLOWING WILL NO LONGER WORK: -----
/** @var File $file */
/** @var TelegramDocument $document */
$file = $tgLog->performApiRequest($getFile);
$document = $tgLog->downloadFile($file);
// ----- INSTEAD, TO MAKE IT ASYNC, USE: -----
$filePromise = $tgLog->performApiRequest($getFile);
$filePromise->then(
function (File $file) use ($tgLog) {
$documentPromise = $tgLog->downloadFile($file);
$documentPromise->then(function (TelegramDocument $document) {
echo '<pre>';
var_dump($document);
echo '</pre>';
});
}
);
$loop->run();
However, any code where you do not process the reply passed back by performApiRequest
will still work, e.g.:
$tgLog->performApiRequest(new GetMe());
Given that you provide enough time for the request to end before your script ends.
Array types (like UpdatesArray
) now implement the IteratorAggregate
interface. This means that they expose a getIterator()
method, which can be used to get an object you can iterate over
and interact with.
This replaces the old traverseObject()
method, which would yield all individual array elements.
Instead of an exception with a generic \stdClass()
object, every unsuccessful request at Telegram will now throw a ClientException
, which will contain more information about the specific error that is being thrown.
Guzzle does not fit well in an async nature. While it appears to have methods for async requests, this functionality is still blocking. Therefore it was deemed a better choice to use the React\HttpClient backend instead, which is async by design.