1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 11:18:59 +01:00

Merge branch 'v8' into story

This commit is contained in:
Daniil Gentili 2023-09-01 15:49:21 +02:00
commit c879e85b6b
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
42 changed files with 218 additions and 144 deletions

View File

@ -6,14 +6,14 @@ clone:
event:
- tag
- push
image: woodpeckerci/plugin-git:v1.5.0
image: woodpeckerci/plugin-git
settings:
depth: 1
lfs: false
recursive: false
tags: true
pipeline:
steps:
variants:
image: docker:cli
secrets: [docker_username, docker_password]

View File

@ -12,14 +12,14 @@ clone:
event:
- tag
- push
image: woodpeckerci/plugin-git:v1.5.0
image: woodpeckerci/plugin-git
settings:
depth: 1
lfs: false
recursive: false
tags: true
pipeline:
steps:
build:
group: build
image: danog/madelineproto:next
@ -63,3 +63,4 @@ services:
depends_on:
- build-docker
- test

View File

@ -5,14 +5,14 @@ clone:
when:
event:
- tag
image: woodpeckerci/plugin-git:v1.5.0
image: woodpeckerci/plugin-git
settings:
depth: 1
lfs: false
recursive: false
tags: true
pipeline:
steps:
variants:
image: docker:cli
secrets: [docker_username, docker_password]

38
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,38 @@
matrix:
php:
- "8.1"
platform:
- linux/arm64
platform: ${platform}
clone:
git:
when:
event:
- tag
- push
- pull_request
image: woodpeckerci/plugin-git
settings:
depth: 1
lfs: false
recursive: false
tags: true
steps:
test:
group: test
image: danog/madelineproto:next
when:
event:
- tag
- push
- pull_request
environment:
- PHP_VERSION=${php}
- PLATFORM=${platform}
- TAG=${CI_COMMIT_TAG}
commands:
- apk add bash
- tests/test.sh

View File

@ -58,6 +58,7 @@ 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!
* [`simpleBot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/simpleBot.php) - Extremely basic example
* [`tgstories_dl_bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/tgstories_dl_bot.php) - Source code of [@tgstories_dl_bot](https://t.me/tgstories_dl_bot) - Bot to download any Telegram Story!
* [`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!
@ -111,6 +112,13 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* [danog\MadelineProto\Broadcast\Progress »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/Broadcast/Progress.html)
* [Full property list »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/Broadcast/Progress.html#properties)
* [Full bound method list »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/Broadcast/Progress.html#method-list)
* [danog\MadelineProto\EventHandler\Message\Service\DialogChannelMigrateFrom »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogChannelMigrateFrom.html) - Indicates the channel was [migrated](https://core.telegram.org/api/channel)
* [danog\MadelineProto\EventHandler\Message\Service\DialogChatMigrateTo »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogChatMigrateTo.html) - Indicates the chat was [migrated](https://core.telegram.org/api/channel)
* [danog\MadelineProto\EventHandler\Message\Service\DialogPeerRequested »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogPeerRequested.html) - Contains info about a peer that the user shared with the bot after clicking on a [keyboardButtonRequestPeer](https://docs.madelineproto.xyz/API_docs/constructors/keyboardButtonRequestPeer.html)
* [danog\MadelineProto\EventHandler\Message\Service\DialogSuggestProfilePhoto »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogSuggestProfilePhoto.html) - A new profile picture was suggested using [photos.uploadContactProfilePhoto](https://docs.madelineproto.xyz/API_docs/methods/photos.uploadContactProfilePhoto.html)
* [danog\MadelineProto\EventHandler\Message\Service\DialogTopicCreated »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogTopicCreated.html) - A [forum topic](https://core.telegram.org/api/forum#forum-topics)
* [danog\MadelineProto\EventHandler\Message\Service\DialogTopicEdited »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogTopicEdited.html) - [Forum topic](https://core.telegram.org/api/forum#forum-topics)
* [danog\MadelineProto\EventHandler\Message\Service\DialogWebView »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/EventHandler/Message/Service/DialogWebView.html) - Data from an opened [reply keyboard bot web app](https://core.telegram.org/api/bots/webapps) was relayed to the bot that owns it (user & bot side service message)
* [danog\MadelineProto\VoIP »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/VoIP.html)
* [Full property list »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/VoIP.html#properties)
* [Full bound method list »](https://docs.madelineproto.xyz/PHP/danog/MadelineProto/VoIP.html#method-list)
@ -339,7 +347,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#mtprototobotapi-array-data-array" name="MTProtoToBotAPI">Convert MTProto parameters to bot API parameters: MTProtoToBotAPI</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#tdtotdcli-mixed-params-mixed" name="tdToTdcli">Convert TD parameters to tdcli: tdToTdcli</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#tdtomtproto-array-params-array" name="tdToMTProto">Convert TD to MTProto parameters: tdToMTProto</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#entitiestohtml-string-message-list-array-_-string-offset-int-length-int-entities-bool-allowtelegramtags-false-string" name="entitiesToHtml">Convert a message and a set of entities to HTML: entitiesToHtml</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#entitiestohtml-string-message-list-danog-madelineproto-eventhandler-message-entities-messageentity-array-_-string-offset-int-length-int-entities-bool-allowtelegramtags-false-string" name="entitiesToHtml">Convert a message and a set of entities to HTML: entitiesToHtml</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.convertToGigagroup.html" name="channels.convertToGigagroup">Convert a supergroup to a gigagroup, when requested by channel suggestions: channels.convertToGigagroup</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#fromsupergroup-int-id-int" name="fromSupergroup">Convert bot API channel ID to MTProto channel ID: fromSupergroup</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#botapitomtproto-array-arguments-array" name="botAPIToMTProto">Convert bot API parameters to MTProto parameters: botAPIToMTProto</a>

View File

@ -71,7 +71,6 @@
"bamarni/composer-bin-plugin": "1.8.2",
"symfony/yaml": "^6.0",
"amphp/http-server": "^3",
"leproxy/leproxy": "^0.2.2",
"revolt/event-loop-adapter-react": "^1",
"dg/bypass-finals": "dev-master"
},
@ -114,11 +113,6 @@
"@cs-fix",
"@psalm"
],
"check": [
"@test",
"@cs",
"@psalm"
],
"test-php7": "tests/test-conversion.sh 70",
"test-php56": "tests/test-conversion.sh 5",
"cs": "PHP_CS_FIXER_IGNORE_ENV=1 php -d pcre.jit=0 vendor/bin/php-cs-fixer fix -v --diff --dry-run",

2
docs

@ -1 +1 @@
Subproject commit f9479b5ed73a5140b98bb70bb48f3c8b3e551a38
Subproject commit fd37b433741080d7df00d12e9c28e63bb999cd2a

View File

@ -12,7 +12,7 @@ use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
use danog\MadelineProto\SimpleEventHandler;
// Load via composer
// Load via composer (RECOMMENDED, see https://docs.madelineproto.xyz/docs/INSTALLATION.html#composer-from-scratch)
if (file_exists('vendor/autoload.php')) {
require_once 'vendor/autoload.php';
} else {

View File

@ -412,8 +412,15 @@
<code><![CDATA[$this->replyCache]]></code>
<code><![CDATA[$this->replyCache]]></code>
</InvalidReturnStatement>
</file>
<file src="src/EventHandler/Filter/AbstractFilterFromSender.php">
<PropertyNotSetInConstructor>
<code>$replyCache</code>
<code>$peerResolved</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Filter/AbstractFilterFromSenders.php">
<PropertyNotSetInConstructor>
<code>$peersResolved</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Filter/FilterFromAdmin.php">
@ -421,16 +428,6 @@
<code>$adminIds</code>
</MissingConstructor>
</file>
<file src="src/EventHandler/Filter/FilterFromSender.php">
<PropertyNotSetInConstructor>
<code>$peerResolved</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Filter/FilterFromSenders.php">
<PropertyNotSetInConstructor>
<code>$peersResolved</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Filter/FilterPeer.php">
<PropertyNotSetInConstructor>
<code>$peerResolved</code>
@ -440,13 +437,9 @@
<PropertyTypeCoercion>
<code>$matches</code>
<code>$matches</code>
<code>$matches</code>
</PropertyTypeCoercion>
</file>
<file src="src/EventHandler/Filter/FilterSender.php">
<PropertyNotSetInConstructor>
<code>$peerResolved</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Media.php">
<PossiblyNullArrayAccess>
<code><![CDATA[$this->botApiFileId]]></code>
@ -560,10 +553,6 @@
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message.php">
<ArgumentTypeCoercion>
<code><![CDATA[$this->entities]]></code>
<code><![CDATA[$this->entities]]></code>
</ArgumentTypeCoercion>
<LessSpecificReturnStatement>
<code><![CDATA[$this->getClient()->wrapMessage($this->getClient()->extractMessage($result))]]></code>
</LessSpecificReturnStatement>
@ -576,7 +565,6 @@
<PropertyNotSetInConstructor>
<code>$html</code>
<code>$htmlTelegram</code>
<code>Message</code>
</PropertyNotSetInConstructor>
<PropertyTypeCoercion>
<code><![CDATA[isset($rawMessage['media'])
@ -591,52 +579,38 @@
<PropertyNotSetInConstructor>
<code>ChannelMessage</code>
<code>ChannelMessage</code>
<code>ChannelMessage</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/GroupMessage.php">
<PropertyNotSetInConstructor>
<code>GroupMessage</code>
<code>GroupMessage</code>
<code>GroupMessage</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/PrivateMessage.php">
<LessSpecificReturnStatement>
<code><![CDATA[$this->getClient()->wrapMessage($this->getClient()->extractMessage($result))]]></code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<code>DialogScreenshotTaken</code>
</MoreSpecificReturnType>
<NullableReturnStatement>
<code><![CDATA[$this->getClient()->wrapMessage($this->getClient()->extractMessage($result))]]></code>
</NullableReturnStatement>
<PropertyNotSetInConstructor>
<code>PrivateMessage</code>
<code>PrivateMessage</code>
<code>PrivateMessage</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/Service/DialogCreated.php">
<PropertyNotSetInConstructor>
<code>DialogCreated</code>
</PropertyNotSetInConstructor>
<file src="src/EventHandler/Participant/Banned.php">
<PossiblyNullPropertyAssignmentValue>
<code><![CDATA[$API->getIdInternal($rawParticipant['peer'])]]></code>
</PossiblyNullPropertyAssignmentValue>
</file>
<file src="src/EventHandler/Message/Service/DialogMemberLeft.php">
<PropertyNotSetInConstructor>
<code>DialogMemberLeft</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/Service/DialogMembersJoined.php">
<PropertyNotSetInConstructor>
<code>DialogMembersJoined</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/Service/DialogMessagePinned.php">
<PropertyNotSetInConstructor>
<code>DialogMessagePinned</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/Service/DialogPhotoChanged.php">
<PropertyNotSetInConstructor>
<code>DialogPhotoChanged</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/EventHandler/Message/Service/DialogTitleChanged.php">
<PropertyNotSetInConstructor>
<code>DialogTitleChanged</code>
</PropertyNotSetInConstructor>
<file src="src/EventHandler/Participant/Left.php">
<PossiblyNullPropertyAssignmentValue>
<code><![CDATA[$API->getIdInternal($rawParticipant['peer'])]]></code>
</PossiblyNullPropertyAssignmentValue>
</file>
<file src="src/EventHandler/Query/ChatTrait.php">
<MoreSpecificReturnType>
@ -1609,6 +1583,10 @@
'_' => 'messageMediaPhoto',
'photo' => $message['action']['photo']
])]]></code>
<code><![CDATA[$this->wrapMedia([
'_' => 'messageMediaPhoto',
'photo' => $message['action']['photo']
])]]></code>
</ArgumentTypeCoercion>
<InaccessibleProperty>
<code><![CDATA[$last->nextSent]]></code>
@ -1620,6 +1598,11 @@
<code>getUpdatesState</code>
<code>loadUpdateState</code>
</MissingReturnType>
<PossiblyNullArgument>
<code><![CDATA[$this->getIdInternal($message['action']['from_id'])]]></code>
<code><![CDATA[$this->getIdInternal($message['action']['peer'])]]></code>
<code><![CDATA[$this->getIdInternal($message['action']['to_id'])]]></code>
</PossiblyNullArgument>
<PossiblyNullArrayAccess>
<code><![CDATA[$this->authorization['user']]]></code>
<code><![CDATA[$this->authorization['user']]]></code>
@ -1801,6 +1784,9 @@
<ArgumentTypeCoercion>
<code><![CDATA[$length<<1]]></code>
</ArgumentTypeCoercion>
<InvalidArgument>
<code>$entities</code>
</InvalidArgument>
</file>
<file src="src/Stream/ADNLTransport/ADNLStream.php">
<MissingPropertyType>

@ -1 +1 @@
Subproject commit e0f1a275a4b610addd13a835c82ca31b98ffab35
Subproject commit 5ac5e7a012be37cf4931c1edc0d516a72793ac16

View File

@ -535,7 +535,13 @@ final class Blacklist {
\fwrite($handle, "use Amp\\Cancellation;\n");
\fwrite($handle, "use Amp\\Http\\Server\\Request as ServerRequest;\n");
\fwrite($handle, "use danog\\MadelineProto\\Broadcast\\Action;\n");
$had = [];
foreach (ClassFinder::getClassesInNamespace(\danog\MadelineProto\EventHandler::class, ClassFinder::RECURSIVE_MODE) as $class) {
$name = \basename(\str_replace('\\', '//', $class));
if (isset($had[$name])) {
continue;
}
$had[$name] = true;
\fwrite($handle, "use $class;\n");
}
/** @psalm-suppress UndefinedClass */

View File

@ -225,7 +225,7 @@ trait Methods
$header .= "YOU CANNOT USE THIS METHOD IN MADELINEPROTO\n\n\n\n\n";
}
if (\in_array($method, ['messages.getHistory', 'messages.getMessages', 'channels.getMessages'], true)) {
$header .= "# Warning: flood wait\n**Warning: this method is prone to rate limiting with flood waits, please use the [updates event handler, instead &raquo;](/docs/UPDATES.html#async-event-driven)**\n\n";
$header .= "# Warning: flood wait\n**Warning: this method is prone to rate limiting with flood waits, **which can lead to !!! ACCOUNT BANS !!!**, please use the [updates event handler, instead (which is 100% safe) &raquo;](/docs/UPDATES.html#async-event-driven)**\n\n";
$header .= "# Warning: non-realtime results\n**Warning: this method is not suitable for receiving messages in real-time from chats and users, please use the [updates event handler, instead &raquo;](/docs/UPDATES.html#async-event-driven)**\n\n";
$header .= "# Warning: this is probably NOT what you need\nYou probably need to use the [updates event handler, instead &raquo;](/docs/UPDATES.html#async-event-driven) :)\n\n";
}

View File

@ -117,7 +117,7 @@ abstract class AbstractMessage extends Update implements SimpleFilters
return $this->replyToMsgId !== null;
}
protected readonly ?self $replyCache;
protected ?self $replyCache = null;
protected bool $replyCached = false;
/**
* Get replied-to message.

View File

@ -112,7 +112,7 @@ abstract class Media extends IpcCapable implements JsonSerializable
/**
* Get a readable amp stream with the file contents.
*
* @param ?(callable(float, float, float): void) $cb Progress callback
* @param (callable(float, float, float): void)|null $cb Progress callback
*/
public function getStream(?callable $cb = null, int $offset = 0, int $end = -1): ReadableStream
{

View File

@ -45,9 +45,8 @@ final class Gif extends AbstractVideo
}
/**
* Add GIF to saved gifs list
* Add GIF to saved gifs list.
*
* @return bool
*/
public function save(): bool
{
@ -61,9 +60,8 @@ final class Gif extends AbstractVideo
}
/**
* Remove GIF from saved gifs list
* Remove GIF from saved gifs list.
*
* @return bool
*/
public function unsave(): bool
{

View File

@ -18,14 +18,14 @@ namespace danog\MadelineProto\EventHandler\Message;
use AssertionError;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant\Left;
use danog\MadelineProto\EventHandler\Participant\Admin;
use danog\MadelineProto\EventHandler\Participant\Member;
use danog\MadelineProto\EventHandler\Participant\MySelf;
use danog\MadelineProto\EventHandler\Participant\Banned;
use danog\MadelineProto\EventHandler\Participant\Creator;
use danog\MadelineProto\EventHandler\Participant\Left;
use danog\MadelineProto\EventHandler\Participant\Member;
use danog\MadelineProto\EventHandler\Participant\MySelf;
use danog\MadelineProto\MTProto;
/**
* Represents an incoming or outgoing channel message.
@ -42,7 +42,7 @@ final class ChannelMessage extends Message
}
/**
* Disable message signatures in channels
* Disable message signatures in channels.
*/
public function disableSignatures(): void
{
@ -56,7 +56,7 @@ final class ChannelMessage extends Message
}
/**
* Enable message signatures in channels
* Enable message signatures in channels.
*/
public function enableSignatures(): void
{
@ -70,16 +70,14 @@ final class ChannelMessage extends Message
}
/**
* Get info about a [channel/supergroup](https://core.telegram.org/api/channel) participant
* Get info about a [channel/supergroup](https://core.telegram.org/api/channel) participant.
*
* @param string|integer $member Participant to get info about.
* @return Participant
* @throws AssertionError
*/
public function getMember(string|int $member): Participant
{
$client = $this->getClient();
$member = $client->getId($member);
$result = $client->methodCallAsyncRead(
'channels.getParticipant',
[

View File

@ -23,9 +23,13 @@ abstract class MessageEntity implements JsonSerializable
$this->length = $rawEntities['length'];
}
public static function fromRawEntities(array $entities)
/**
* @param list<array> $entities
* @return list<self>
*/
public static function fromRawEntities(array $entities): array
{
$create = static fn (array $entity): MessageEntity => match ($entity['_']) {
return \array_map(static fn (array $entity): MessageEntity => match ($entity['_']) {
'messageEntityMention' => new Mention($entity),
'messageEntityHashtag' => new Hashtag($entity),
'messageEntityBotCommand' => new BotCommand($entity),
@ -46,8 +50,7 @@ abstract class MessageEntity implements JsonSerializable
'messageEntitySpoiler' => new Spoiler($entity),
'messageEntityCustomEmoji' => new CustomEmoji($entity),
default => new Unknown($entity)
};
return \array_map(fn (array $entity) => $create($entity), $entities);
}, $entities);
}
/** @internal */
public function jsonSerialize(): mixed

View File

@ -19,29 +19,28 @@ namespace danog\MadelineProto\EventHandler\Message;
use AssertionError;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant\Left;
use danog\MadelineProto\EventHandler\Participant\Admin;
use danog\MadelineProto\EventHandler\Participant\Member;
use danog\MadelineProto\EventHandler\Participant\MySelf;
use danog\MadelineProto\EventHandler\Participant\Banned;
use danog\MadelineProto\EventHandler\Participant\Creator;
use danog\MadelineProto\EventHandler\Participant\Left;
use danog\MadelineProto\EventHandler\Participant\Member;
use danog\MadelineProto\EventHandler\Participant\MySelf;
/**
* Represents an incoming or outgoing group message.
*/
final class GroupMessage extends Message
{
/**
* Get info about a [channel/supergroup](https://core.telegram.org/api/channel) participant
* Get info about a [channel/supergroup](https://core.telegram.org/api/channel) participant.
*
* @param string|integer|null $member Participant to get info about; can be empty or null to get info about the sender of the message.
* @return Participant
* @throws AssertionError
*/
public function getMember(string|int|null $member = null): Participant
{
$client = $this->getClient();
$member ??= $this->senderId;
$member = $client->getId($member);
$result = $client->methodCallAsyncRead(
'channels.getParticipant',
[

View File

@ -25,9 +25,8 @@ use danog\MadelineProto\EventHandler\Message\Service\DialogScreenshotTaken;
final class PrivateMessage extends Message
{
/**
* Notify the other user in a private chat that a screenshot of the chat was taken
* Notify the other user in a private chat that a screenshot of the chat was taken.
*
* @return DialogScreenshotTaken
*/
public function screenShot(): DialogScreenshotTaken
{

View File

@ -19,6 +19,9 @@ namespace danog\MadelineProto\EventHandler\Message\Service;
use danog\MadelineProto\EventHandler\Message\ServiceMessage;
use danog\MadelineProto\MTProto;
/**
* Represents a service message about a group call.
*/
abstract class AbstractDialogGroupCall extends ServiceMessage
{
/** @internal */

View File

@ -20,7 +20,7 @@ use danog\MadelineProto\EventHandler\Message\ServiceMessage;
use danog\MadelineProto\MTProto;
/**
* The channel was created
* The channel was created.
*/
final class DialogChannelCreated extends ServiceMessage
{

View File

@ -28,7 +28,7 @@ final class DialogGameScore extends ServiceMessage
MTProto $API,
array $rawMessage,
array $info,
/** Game ID */
public readonly int $gameId,
/** Score */

View File

@ -17,8 +17,8 @@
namespace danog\MadelineProto\EventHandler\Message\Service;
use danog\MadelineProto\EventHandler\Message\ServiceMessage;
use danog\MadelineProto\VoIP\DiscardReason;
use danog\MadelineProto\MTProto;
use danog\MadelineProto\VoIP\DiscardReason;
/**
* A phone call.

View File

@ -28,7 +28,7 @@ final class DialogTopicEdited extends ServiceMessage
MTProto $API,
array $rawMessage,
array $info,
/** Topic name. */
public readonly string $title,
/** ID of the [custom emoji](https://core.telegram.org/api/custom-emoji) used as topic icon. */

View File

@ -21,7 +21,7 @@ use ReflectionClass;
use ReflectionProperty;
/**
* Info about a channel participant
* Info about a channel participant.
*/
abstract class Participant implements JsonSerializable
{
@ -35,4 +35,4 @@ abstract class Participant implements JsonSerializable
}
return $res;
}
}
}

View File

@ -20,7 +20,7 @@ use danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant\Rights\Admin as AdminRights;
/**
* Admin
* Admin.
*/
final class Admin extends Participant
{
@ -61,4 +61,4 @@ final class Admin extends Participant
$this->rank = $rawParticipant['rank'] ?? 'admin';
$this->adminRights = new AdminRights($rawParticipant['admin_rights']);
}
}
}

View File

@ -18,10 +18,11 @@ namespace danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant\Rights\Banned as BannedRights;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\MTProto;
/**
* Banned/kicked user
* Banned/kicked user.
*/
final class Banned extends Participant
{
@ -42,11 +43,11 @@ final class Banned extends Participant
/** @internal */
public function __construct(
MTProto $API,
MTProto|Client $API,
array $rawParticipant
) {
$this->left = $rawParticipant['left'];
$this->peer = $API->getIdInternal ($rawParticipant['peer']);
$this->peer = $API->getIdInternal($rawParticipant['peer']);
$this->kickedBy = $rawParticipant['kicked_by'];
$this->date = $rawParticipant['date'];
$this->bannedRights = new BannedRights($rawParticipant['banned_rights']);

View File

@ -20,7 +20,7 @@ use danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant\Rights\Admin as AdminRights;
/**
* Channel/supergroup creator
* Channel/supergroup creator.
*/
final class Creator extends Participant
{
@ -41,4 +41,4 @@ final class Creator extends Participant
$this->adminRights = new AdminRights($rawParticipant['adminRights']);
$this->rank = $rawParticipant['rank'] ?? 'Owner';
}
}
}

View File

@ -17,22 +17,22 @@
namespace danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\MTProto;
/**
* A participant that left the channel/supergroup
* A participant that left the channel/supergroup.
*/
final class Left extends Participant
{
/** The peer that left */
public readonly int $peer;
/** @internal */
public function __construct(
MTProto $API,
MTProto|Client $API,
array $rawParticipant
) {
$this->peer = $API->getIdInternal ($rawParticipant['peer']);
$this->peer = $API->getIdInternal($rawParticipant['peer']);
}
}
}

View File

@ -19,7 +19,7 @@ namespace danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant;
/**
* Channel/supergroup participant
* Channel/supergroup participant.
*/
final class Member extends Participant
{
@ -36,4 +36,4 @@ final class Member extends Participant
$this->userId = $rawParticipant['user_id'];
$this->date = $rawParticipant['date'];
}
}
}

View File

@ -19,7 +19,7 @@ namespace danog\MadelineProto\EventHandler\Participant;
use danog\MadelineProto\EventHandler\Participant;
/**
* Myself
* Myself.
*/
final class MySelf extends Participant
{
@ -44,4 +44,4 @@ final class MySelf extends Participant
$this->inviterId = $rawParticipant['inviter_id'] ?? null;
$this->date = $rawParticipant['date'];
}
}
}

View File

@ -32,4 +32,4 @@ abstract class Rights implements JsonSerializable
}
return $res;
}
}
}

View File

@ -28,7 +28,7 @@ final class Admin extends Rights
/** If set, allows the admin to post messages in the [channel](https://core.telegram.org/api/channel) */
public readonly bool $postMessages;
/** If set, allows the admin to also edit messages from other admins in the [channel](https://core.telegram.org/api/channel) */
public readonly bool $editMessages;
@ -53,10 +53,10 @@ final class Admin extends Rights
/** If set, allows the admin to change group call/livestream settings */
public readonly bool $manageCall;
/** Set this flag if none of the other flags are set,
/** Set this flag if none of the other flags are set,
* but you still want the user to be an admin: if this or any of the other flags are set,
* the admin can get the chat [admin log](https://core.telegram.org/api/recent-actions), get [chat statistics](https://core.telegram.org/api/stats), get [message statistics in channels](https://core.telegram.org/api/stats), get channel members,
* see anonymous administrators in supergroups and ignore slow mode.
* see anonymous administrators in supergroups and ignore slow mode.
*/
public readonly bool $other;
@ -80,4 +80,4 @@ final class Admin extends Rights
$this->other = $rawRights['other'];
$this->manageTopics = $rawRights['manage_topics'];
}
}
}

View File

@ -108,4 +108,4 @@ final class Banned extends Rights
$this->sendPlain = $rawRights['send_plain'];
$this->untilDate = $rawRights['until_date'];
}
}
}

View File

@ -26,6 +26,16 @@ use danog\MadelineProto\EventHandler\Media\Document;
use danog\MadelineProto\EventHandler\Media\Photo;
use danog\MadelineProto\EventHandler\Media\Video;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Message\Entities\Code;
use danog\MadelineProto\EventHandler\Message\Entities\Email;
use danog\MadelineProto\EventHandler\Message\Entities\Mention;
use danog\MadelineProto\EventHandler\Message\Entities\MessageEntity;
use danog\MadelineProto\EventHandler\Message\Entities\Phone;
use danog\MadelineProto\EventHandler\Message\Entities\Pre;
use danog\MadelineProto\EventHandler\Message\Entities\Spoiler;
use danog\MadelineProto\EventHandler\Message\Entities\Url;
use danog\MadelineProto\EventHandler\Participant\Admin;
use danog\MadelineProto\EventHandler\Participant\Member;
use danog\MadelineProto\EventHandler\Update;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\Ipc\EventHandlerProxy;
@ -501,7 +511,7 @@ abstract class InternalDoc
/**
* Convert a message and a set of entities to HTML.
*
* @param list<array{_: string, offset: int, length: int, ...}> $entities
* @param list<MessageEntity|array{_: string, offset: int, length: int}> $entities
* @param bool $allowTelegramTags Whether to allow telegram-specific tags like tg-spoiler, tg-emoji, mention links and so on...
*/
public static function entitiesToHtml(string $message, array $entities, bool $allowTelegramTags = false): string

View File

@ -88,7 +88,10 @@ trait FilesAbstraction
return new VideoSticker($this, $media, $attr, $has_video, $protected);
}
\assert($has_document_photo !== null);
if ($has_document_photo === null) {
throw new AssertionError("has_document_photo === null: ".\json_encode($media['document']));
}
if ($attr['mask']) {
return new MaskSticker($this, $media, $attr, $has_document_photo, $protected);
}
@ -109,12 +112,16 @@ trait FilesAbstraction
: new Audio($this, $media, $attr, $protected);
}
if ($t === 'documentAttributeCustomEmoji') {
\assert($has_document_photo !== null);
if ($has_document_photo === null) {
throw new AssertionError("has_document_photo === null: ".\json_encode($media['document']));
}
return new CustomEmoji($this, $media, $attr, $has_document_photo, $protected);
}
}
if ($has_animated) {
\assert($has_video !== null);
if ($has_video === null) {
throw new AssertionError("has_video === null: ".\json_encode($media['document']));
}
return new Gif($this, $media, $has_video, $protected);
}
if ($has_video) {

View File

@ -32,11 +32,18 @@ use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Message\ChannelMessage;
use danog\MadelineProto\EventHandler\Message\GroupMessage;
use danog\MadelineProto\EventHandler\Message\PrivateMessage;
use danog\MadelineProto\EventHandler\Message\Service\DialogChannelCreated;
use danog\MadelineProto\EventHandler\Message\Service\DialogChannelMigrateFrom;
use danog\MadelineProto\EventHandler\Message\Service\DialogChatJoinedByLink;
use danog\MadelineProto\EventHandler\Message\Service\DialogChatMigrateTo;
use danog\MadelineProto\EventHandler\Message\Service\DialogContactSignUp;
use danog\MadelineProto\EventHandler\Message\Service\DialogCreated;
use danog\MadelineProto\EventHandler\Message\Service\DialogGameScore;
use danog\MadelineProto\EventHandler\Message\Service\DialogGeoProximityReached;
use danog\MadelineProto\EventHandler\Message\Service\DialogGiftPremium;
use danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallEnded;
use danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallInvited;
use danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallScheduled;
use danog\MadelineProto\EventHandler\Message\Service\DialogHistoryCleared;
use danog\MadelineProto\EventHandler\Message\Service\DialogMemberJoinedByRequest;
use danog\MadelineProto\EventHandler\Message\Service\DialogMemberLeft;
@ -44,22 +51,15 @@ use danog\MadelineProto\EventHandler\Message\Service\DialogMembersJoined;
use danog\MadelineProto\EventHandler\Message\Service\DialogMessagePinned;
use danog\MadelineProto\EventHandler\Message\Service\DialogPeerRequested;
use danog\MadelineProto\EventHandler\Message\Service\DialogPhoneCall;
use danog\MadelineProto\EventHandler\Message\Service\DialogChannelCreated;
use danog\MadelineProto\EventHandler\Message\Service\DialogChannelMigrateFrom;
use danog\MadelineProto\EventHandler\Message\Service\DialogChatMigrateTo;
use danog\MadelineProto\EventHandler\Message\Service\DialogPhotoChanged;
use danog\MadelineProto\EventHandler\Message\Service\DialogTitleChanged;
use danog\MadelineProto\EventHandler\Message\Service\DialogScreenshotTaken;
use danog\MadelineProto\EventHandler\Message\Service\DialogSetChatTheme;
use danog\MadelineProto\EventHandler\Message\Service\DialogSetTTL;
use danog\MadelineProto\EventHandler\Message\Service\DialogSuggestProfilePhoto;
use danog\MadelineProto\EventHandler\Message\Service\DialogTitleChanged;
use danog\MadelineProto\EventHandler\Message\Service\DialogTopicCreated;
use danog\MadelineProto\EventHandler\Message\Service\DialogTopicEdited;
use danog\MadelineProto\EventHandler\Message\Service\DialogWebView;
use danog\MadelineProto\EventHandler\Message\Service\DialogGiftPremium;
use danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallEnded;
use danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallInvited;
use danog\MadelineProto\EventHandler\Message\Service\DialogGroupCall\GroupCallScheduled;
use danog\MadelineProto\EventHandler\Query\ChatButtonQuery;
use danog\MadelineProto\EventHandler\Query\ChatGameQuery;
use danog\MadelineProto\EventHandler\Query\InlineButtonQuery;
@ -447,13 +447,13 @@ trait UpdateHandler
$this,
$message,
$info,
$message['action']['inviter_id'],
$message['action']['inviter_id'],
),
'messageActionChannelCreate' => new DialogChannelCreated(
$this,
$message,
$info,
$message['action']['title'],
$message['action']['title'],
),
'messageActionChatMigrateTo' => new DialogChatMigrateTo(
$this,

View File

@ -133,14 +133,16 @@ abstract class StrTools extends Extension
/**
* Convert a message and a set of entities to HTML.
*
* @param list<MessageEntity> $entities
* @param list<MessageEntity|array{_: string, offset: int, length: int}> $entities
* @param bool $allowTelegramTags Whether to allow telegram-specific tags like tg-spoiler, tg-emoji, mention links and so on...
*/
public static function entitiesToHtml(string $message, array $entities, bool $allowTelegramTags = false): string
{
$insertions = [];
if (isset($entities[0]) && \is_array($entities[0])) {
$entities = MessageEntity::fromRawEntities($entities);
}
foreach ($entities as $entity) {
$entity = isset($entity) && \is_array($entity) ? MessageEntity::fromRawEntities([$entity])[0] : $entity;
[$offset, $length] = [$entity->offset, $entity->length];
$insertions[$offset] ??= '';
$insertions[$offset] .= match (true) {

View File

@ -298,7 +298,6 @@ final class ConnectionContext
/**
* Get the inputClientProxy proxy MTProto object.
*
* @return array
*/
public function getInputClientProxy(): array|null
{

View File

@ -39,14 +39,13 @@ enum DiscardReason implements JsonSerializable
/**
* @internal
*
* @param ?string
* @throws AssertionError
*/
public static function fromString(?string $name): ?DiscardReason
{
if ($name === null)
if ($name === null) {
return null;
}
$newName = \strtoupper(\substr($name, 22));
foreach (DiscardReason::cases() as $case) {
if ($case->name === $newName) {

20
tests/test.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash -ex
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
mv composer.phar /usr/local/bin/composer
apk add procps git unzip github-cli openssh
rmdir docs
curl -L https://github.com/danog/MadelineProtoDocs/archive/refs/heads/master.tar.gz | tar -xz
mv MadelineProtoDocs-master/ docs
git submodule init schemas
git submodule update schemas
composer update
composer build
if [ "$(git diff)" != "" ]; then echo "Please run composer build!"; exit 1; fi

View File

@ -146,6 +146,9 @@ function printTypes(array $types, string $type): string
}
$refl = new ReflectionClass($class);
$link = "https://docs.madelineproto.xyz/PHP/".str_replace('\\', '/', $class).'.html';
if (!$refl->getDocComment()) {
throw new AssertionError("No documentation for $class!");
}
$f = $b->create($refl->getDocComment())->getSummary();
if ($refl->hasMethod('__construct')) {
$c = $refl->getMethod('__construct');