mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 05:38:57 +01:00
Fix
This commit is contained in:
parent
7e69782e74
commit
b896ae8699
@ -25,3 +25,4 @@ Fixes:
|
||||
- Reduce memory usage during flood waits by tweaking config defaults.
|
||||
- Reduce memory usage by clearing the min database automatically as needed.
|
||||
- Automatically try caching all dialogs if a peer not found error is about to be thrown
|
||||
- Fix some issues with pure phar installs
|
||||
|
@ -309,6 +309,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#tocamelcase-string-input-string" name="toCamelCase">Convert to camelCase: toCamelCase</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#tosnakecase-string-input-string" name="toSnakeCase">Convert to snake_case: toSnakeCase</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#packunsignedint-int-value-string" name="packUnsignedInt">Convert value to unsigned base256 int: packUnsignedInt</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#stringtostream-string-str-amp-bytestream-readablebuffer" name="stringToStream">Converts a string into an async amphp stream: stringToStream</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.createForumTopic.html" name="channels.createForumTopic">Create a forum topic; requires manage_topics rights: channels.createForumTopic</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.createChannel.html" name="channels.createChannel">Create a supergroup/channel: channels.createChannel</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/phone.createGroupCall.html" name="phone.createGroupCall">Create a group call or livestream: phone.createGroupCall</a>
|
||||
|
2
docs
2
docs
@ -1 +1 @@
|
||||
Subproject commit 6936aa2703675f1b144d613e69e4922b51ea358f
|
||||
Subproject commit d6cc1fffc9ce3a14d44bb8dd30fdb81e7101e361
|
@ -24,6 +24,11 @@ use danog\MadelineProto\Broadcast\Progress;
|
||||
use danog\MadelineProto\Broadcast\Status;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\Attributes\Cron;
|
||||
use danog\MadelineProto\EventHandler\Attributes\Handler;
|
||||
use danog\MadelineProto\EventHandler\Filter\FilterCommand;
|
||||
use danog\MadelineProto\EventHandler\Filter\FilterText;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\Settings;
|
||||
use danog\MadelineProto\Settings\Database\Mysql;
|
||||
@ -124,85 +129,68 @@ class MyEventHandler extends EventHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle updates from supergroups and channels.
|
||||
*
|
||||
* @param array $update Update
|
||||
*/
|
||||
public function onUpdateNewChannelMessage(array $update): void
|
||||
{
|
||||
$this->onUpdateNewMessage($update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle updates from users.
|
||||
* Handle incoming updates from users, chats and channels.
|
||||
*
|
||||
* 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)
|
||||
* A special onUpdateCustomEvent method can also be defined, to send messages to the event handler from an API instance, using the sendCustomEvent method.
|
||||
*
|
||||
* @param array $update Update
|
||||
*/
|
||||
public function onUpdateNewMessage(array $update): void
|
||||
#[Handler]
|
||||
public function handleMessage(Incoming&Message $message): void
|
||||
{
|
||||
if ($update['message']['_'] === 'messageEmpty') {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger($update);
|
||||
|
||||
// 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;
|
||||
$this->logger($message);
|
||||
|
||||
// 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])) {
|
||||
$this->notifiedChats[$id] = true;
|
||||
if (!isset($this->notifiedChats[$message->chatId])) {
|
||||
$this->notifiedChats[$message->chatId] = true;
|
||||
|
||||
$this->messages->sendMessage(
|
||||
peer: $update,
|
||||
peer: $message->chatId,
|
||||
message: "This userbot is powered by [MadelineProto](https://t.me/MadelineProto)!",
|
||||
reply_to_msg_id: $update['message']['id'] ?? null,
|
||||
reply_to_msg_id: $message->id,
|
||||
parse_mode: 'Markdown'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[FilterCommand('restart')]
|
||||
public function restartCommand(Incoming&Message $message): void
|
||||
{
|
||||
// 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
|
||||
) {
|
||||
if ($message->senderId === $this->adminId) {
|
||||
// Make sure to run in a bash while loop when running via CLI to allow self-restarts.
|
||||
$this->restart();
|
||||
}
|
||||
}
|
||||
|
||||
#[FilterCommand('broadcast')]
|
||||
public function broadcastCommand(Incoming&Message $message): void
|
||||
{
|
||||
// We can broadcast messages to all users.
|
||||
if (($update['message']['message'] ?? '') === '/broadcast'
|
||||
&& $from_id === $this->adminId
|
||||
) {
|
||||
if (!isset($update['message']['reply_to']['reply_to_msg_id'])) {
|
||||
if ($message->senderId === $this->adminId) {
|
||||
if (!$message->replyToMsgId) {
|
||||
$this->messages->sendMessage(
|
||||
peer: $update,
|
||||
peer: $message->senderId,
|
||||
message: "You should reply to the message you want to broadcast.",
|
||||
reply_to_msg_id: $update['message']['id'] ?? null,
|
||||
reply_to_msg_id: $message->id,
|
||||
);
|
||||
return;
|
||||
}
|
||||
$this->broadcastForwardMessages(
|
||||
from_peer: $update,
|
||||
message_ids: [$update['message']['reply_to']['reply_to_msg_id']],
|
||||
from_peer: $message->senderId,
|
||||
message_ids: [$message->replyToMsgId],
|
||||
drop_author: true,
|
||||
pin: true,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (($update['message']['message'] ?? '') === 'ping') {
|
||||
$this->messages->sendMessage(['message' => 'pong', 'peer' => $update]);
|
||||
}
|
||||
#[FilterText('ping')]
|
||||
public function pingCommand(Incoming&Message $message): void
|
||||
{
|
||||
$this->messages->sendMessage(['message' => 'pong', 'peer' => $message->chatId]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,11 @@ use Closure;
|
||||
use danog\Loop\PeriodicLoop;
|
||||
use danog\MadelineProto\Db\DbPropertiesTrait;
|
||||
use danog\MadelineProto\EventHandler\Attributes\Cron;
|
||||
use danog\MadelineProto\EventHandler\Attributes\Handler;
|
||||
use danog\MadelineProto\EventHandler\Attributes\Periodic;
|
||||
use danog\MadelineProto\EventHandler\Filter\Combinator\FiltersAnd;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Handler;
|
||||
use danog\MadelineProto\EventHandler\Filter\FilterAllowAll;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
use Generator;
|
||||
use mysqli;
|
||||
@ -191,18 +192,20 @@ abstract class EventHandler extends AbstractAPI
|
||||
$this->periodicLoops[$method]->start();
|
||||
continue;
|
||||
}
|
||||
if (!($handler = $methodRefl->getAttributes(Handler::class))) {
|
||||
continue;
|
||||
}
|
||||
$filter = $methodRefl->getAttributes(
|
||||
Filter::class,
|
||||
ReflectionAttribute::IS_INSTANCEOF
|
||||
)[0] ?? null;
|
||||
if (!$filter) {
|
||||
continue;
|
||||
if (!($handler = $methodRefl->getAttributes(Handler::class))) {
|
||||
continue;
|
||||
}
|
||||
$filter = new FilterAllowAll;
|
||||
} else {
|
||||
$filter = $filter->newInstance();
|
||||
}
|
||||
$filter = new FiltersAnd(
|
||||
$filter->newInstance(),
|
||||
$filter,
|
||||
Filter::fromReflectionType($methodRefl->getParameters()[0]->getType())
|
||||
);
|
||||
$filter = $filter->initialize($this) ?? $filter;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Combinator;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
@ -9,6 +10,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* NOTs a filter.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterNot extends Filter
|
||||
{
|
||||
public function __construct(private readonly Filter $filter)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Combinator;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Filter\FilterAllowAll;
|
||||
@ -11,6 +12,7 @@ use Webmozart\Assert\Assert;
|
||||
/**
|
||||
* ANDs multiple filters.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FiltersAnd extends Filter
|
||||
{
|
||||
/** @var array<Filter> */
|
||||
@ -27,6 +29,8 @@ final class FiltersAnd extends Filter
|
||||
$filter = $filter->initialize($API) ?? $filter;
|
||||
if ($filter instanceof self) {
|
||||
$final = \array_merge($final, $filter->filters);
|
||||
} else {
|
||||
$final []= $filter;
|
||||
}
|
||||
}
|
||||
$final = \array_filter(
|
||||
@ -34,10 +38,11 @@ final class FiltersAnd extends Filter
|
||||
fn (Filter $f): bool => !$f instanceof FilterAllowAll,
|
||||
);
|
||||
$final = \array_values($final);
|
||||
if (\count($final) === 1) {
|
||||
return $final[0];
|
||||
}
|
||||
return new self(...$final);
|
||||
return match (\count($final)) {
|
||||
0 => new FilterAllowAll,
|
||||
1 => $final[0],
|
||||
default => new self(...$final)
|
||||
};
|
||||
}
|
||||
public function apply(Update $update): bool
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Combinator;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Filter\FilterAllowAll;
|
||||
@ -11,6 +12,7 @@ use Webmozart\Assert\Assert;
|
||||
/**
|
||||
* ORs multiple filters.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FiltersOr extends Filter
|
||||
{
|
||||
/** @var array<Filter> */
|
||||
@ -27,6 +29,8 @@ final class FiltersOr extends Filter
|
||||
$filter = $filter->initialize($API) ?? $filter;
|
||||
if ($filter instanceof self) {
|
||||
$final = \array_merge($final, $filter->filters);
|
||||
} else {
|
||||
$final []= $filter;
|
||||
}
|
||||
}
|
||||
foreach ($final as $f) {
|
||||
@ -34,10 +38,11 @@ final class FiltersOr extends Filter
|
||||
return $f;
|
||||
}
|
||||
}
|
||||
if (\count($final) === 1) {
|
||||
return $final[0];
|
||||
}
|
||||
return new self(...$final);
|
||||
return match (\count($final)) {
|
||||
0 => new FilterAllowAll,
|
||||
1 => $final[0],
|
||||
default => new self(...$final)
|
||||
};
|
||||
}
|
||||
public function apply(Update $update): bool
|
||||
{
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\BasicFilter\Incoming;
|
||||
use danog\MadelineProto\EventHandler\Filter\Combinator\FiltersAnd;
|
||||
use danog\MadelineProto\EventHandler\Filter\Combinator\FiltersOr;
|
||||
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
|
||||
use danog\MadelineProto\EventHandler\SimpleFilter\Outgoing;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
use ReflectionIntersectionType;
|
||||
@ -14,7 +13,6 @@ use ReflectionNamedType;
|
||||
use ReflectionType;
|
||||
use ReflectionUnionType;
|
||||
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
abstract class Filter
|
||||
{
|
||||
abstract public function apply(Update $update): bool;
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow all updates.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterAllowAll extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,17 +2,19 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* Allow only updates of a certain class type.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterClass extends Filter
|
||||
{
|
||||
public function __construct(private readonly string $class)
|
||||
{
|
||||
Assert::true(\is_subclass_of($class, Update::class));
|
||||
Assert::true(\is_subclass_of($class, Update::class), "$class is not a subclass of Update!");
|
||||
}
|
||||
public function apply(Update $update): bool
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
use Webmozart\Assert\Assert;
|
||||
@ -9,11 +10,12 @@ use Webmozart\Assert\Assert;
|
||||
/**
|
||||
* Allow only messages containing the specified command.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterCommand extends Filter
|
||||
{
|
||||
public function __construct(private readonly string $command)
|
||||
{
|
||||
Assert::true(\preg_match("/^\w+$/", $command));
|
||||
Assert::true(\preg_match("/^\w+$/", $command) === 1, "An invalid command was specified!");
|
||||
}
|
||||
public function apply(Update $update): bool
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
use Webmozart\Assert\Assert;
|
||||
@ -9,13 +10,14 @@ use Webmozart\Assert\Assert;
|
||||
/**
|
||||
* Allow only messages containing one of the specified commands.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterCommands extends Filter
|
||||
{
|
||||
private readonly array $commands;
|
||||
public function __construct(string ...$commands)
|
||||
{
|
||||
foreach ($commands as $command) {
|
||||
Assert::true(\preg_match("/^\w+$/", $command));
|
||||
Assert::true(\preg_match("/^\w+$/", $command) === 1, "An invalid command was specified!");
|
||||
}
|
||||
$this->commands = $commands;
|
||||
}
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow only forwarded messages.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterForwarded extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\AbstractMessage;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow only incoming messages.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterIncoming extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow any media messages.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterMedia extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\AbstractMessage;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow only outgoing messages.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterOutgoing extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
@ -9,6 +10,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow messages coming from or sent to a certain peer.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterPeer extends Filter
|
||||
{
|
||||
private readonly int $peerResolved;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
use Webmozart\Assert\Assert;
|
||||
@ -9,6 +10,7 @@ use Webmozart\Assert\Assert;
|
||||
/**
|
||||
* Allow only messages matching the specified regex.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterRegex extends Filter
|
||||
{
|
||||
public function __construct(private readonly string $regex)
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow messages that reply to other messages.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterReply extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\EventHandler\Message\GroupMessage;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
@ -9,6 +10,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow incoming or outgoing group messages made by a certain sender.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterSender extends Filter
|
||||
{
|
||||
private readonly int $peerResolved;
|
||||
|
@ -2,16 +2,22 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
use danog\MadelineProto\EventHandler\Update;
|
||||
|
||||
/**
|
||||
* Allow text-only messages.
|
||||
* Allow only messages with a specific content.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterText extends Filter
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $content
|
||||
) {
|
||||
}
|
||||
public function apply(Update $update): bool
|
||||
{
|
||||
return $update instanceof Message && $update->media === null;
|
||||
return $update instanceof Message && $update->message === $this->content;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\Audio;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches audio files.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterAudio extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\Document;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches documents.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterDocument extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\DocumentPhoto;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches documents containing an image.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterDocumentPhoto extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\Gif;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches GIFs.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterGif extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\Photo;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches photos.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterPhoto extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\RoundVideo;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches round videos.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterRoundVideo extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\AbstractSticker;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches stickers.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterSticker extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\Video;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches videos.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterVideo extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Filter\Media;
|
||||
|
||||
use Attribute;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
use danog\MadelineProto\EventHandler\Media\Voice;
|
||||
use danog\MadelineProto\EventHandler\Message;
|
||||
@ -10,6 +11,7 @@ use danog\MadelineProto\EventHandler\Update;
|
||||
/**
|
||||
* Allow that only matches voice messages.
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD)]
|
||||
final class FilterVoice extends Filter
|
||||
{
|
||||
public function apply(Update $update): bool
|
||||
|
@ -4,11 +4,12 @@ namespace danog\MadelineProto\EventHandler;
|
||||
|
||||
use danog\MadelineProto\Ipc\IpcCapable;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* Represents a generic media.
|
||||
*/
|
||||
abstract class Media extends IpcCapable
|
||||
abstract class Media extends IpcCapable implements JsonSerializable
|
||||
{
|
||||
/** Media filesize */
|
||||
public readonly int $size;
|
||||
@ -20,7 +21,7 @@ abstract class Media extends IpcCapable
|
||||
public readonly string $fileExt;
|
||||
|
||||
/** Media creation date */
|
||||
public readonly bool $creationDate;
|
||||
public readonly int $creationDate;
|
||||
|
||||
/** Media MIME type */
|
||||
public readonly string $mimeType;
|
||||
@ -55,8 +56,16 @@ abstract class Media extends IpcCapable
|
||||
] = $API->getDownloadInfo($rawMedia);
|
||||
$this->fileName = "$name.".$this->fileExt;
|
||||
|
||||
$this->creationDate = $rawMedia['date'];
|
||||
$this->creationDate = ($rawMedia['document'] ?? $rawMedia['photo'])['date'];
|
||||
$this->ttl = $rawMedia['ttl_seconds'] ?? null;
|
||||
$this->spoiler = $rawMedia['spoiler'] ?? false;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
$v = \get_object_vars($this);
|
||||
unset($v['API'], $v['session']);
|
||||
$v['_'] = static::class;
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ final class DocumentPhoto extends Media
|
||||
$this->width = $attribute['w'];
|
||||
$this->height = $attribute['h'];
|
||||
$hasStickers = false;
|
||||
foreach ($rawMedia['attributes'] as ['_' => $t]) {
|
||||
foreach ($rawMedia['document']['attributes'] as ['_' => $t]) {
|
||||
if ($t === 'documentAttributeHasStickers') {
|
||||
$hasStickers = true;
|
||||
break;
|
||||
|
@ -20,7 +20,7 @@ final class Gif extends AbstractVideo
|
||||
) {
|
||||
parent::__construct($API, $rawMedia, $attribute);
|
||||
$hasStickers = false;
|
||||
foreach ($rawMedia['attributes'] as ['_' => $t]) {
|
||||
foreach ($rawMedia['document']['attributes'] as ['_' => $t]) {
|
||||
if ($t === 'documentAttributeHasStickers') {
|
||||
$hasStickers = true;
|
||||
break;
|
||||
|
@ -2,11 +2,18 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler\Media;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
/** Position of the mask */
|
||||
enum MaskPosition
|
||||
enum MaskPosition: int implements JsonSerializable
|
||||
{
|
||||
case Forehead;
|
||||
case Eyes;
|
||||
case Mouth;
|
||||
case Chin;
|
||||
case Forehead = 0;
|
||||
case Eyes = 1;
|
||||
case Mouth = 2;
|
||||
case Chin = 3;
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ final class Photo extends Media
|
||||
) {
|
||||
parent::__construct($API, $rawMedia);
|
||||
$hasStickers = false;
|
||||
foreach ($rawMedia['attributes'] as ['_' => $t]) {
|
||||
foreach ($rawMedia['document']['attributes'] as ['_' => $t]) {
|
||||
if ($t === 'documentAttributeHasStickers') {
|
||||
$hasStickers = true;
|
||||
break;
|
||||
|
@ -20,7 +20,7 @@ final class Video extends AbstractVideo
|
||||
) {
|
||||
parent::__construct($API, $rawMedia, $attribute);
|
||||
$hasStickers = false;
|
||||
foreach ($rawMedia['attributes'] as ['_' => $t]) {
|
||||
foreach ($rawMedia['document']['attributes'] as ['_' => $t]) {
|
||||
if ($t === 'documentAttributeHasStickers') {
|
||||
$hasStickers = true;
|
||||
break;
|
||||
|
@ -30,6 +30,8 @@ abstract class Message extends AbstractMessage
|
||||
|
||||
/** Bot command (if present) */
|
||||
public readonly ?string $command;
|
||||
/** Bot command type (if present) */
|
||||
public readonly ?CommandType $commandType;
|
||||
/** @var list<string> Bot command arguments (if present) */
|
||||
public readonly ?array $commandArgs;
|
||||
|
||||
@ -110,23 +112,22 @@ abstract class Message extends AbstractMessage
|
||||
? $API->wrapMedia($rawMessage['media'])
|
||||
: null;
|
||||
|
||||
if (
|
||||
$this->entities
|
||||
&& $this->entities[0]['_'] === 'messageEntityBotCommand'
|
||||
&& $this->entities[0]['offset'] === 0
|
||||
) {
|
||||
$this->command = StrTools::mbSubstr(
|
||||
$this->message,
|
||||
1,
|
||||
$this->entities[0]['length']-1
|
||||
);
|
||||
if (\in_array($this->message[0] ?? '', ['/', '.', '!'], true)) {
|
||||
$space = \strpos($this->message, ' ', 1) ?: \strlen($this->message);
|
||||
$this->command = \substr($this->message, 1, $space-1);
|
||||
$this->commandArgs = \explode(
|
||||
' ',
|
||||
StrTools::mbSubstr($this->message, $this->entities[0]['length']+1)
|
||||
\substr($this->message, $space+1)
|
||||
);
|
||||
$this->commandType = match ($this->message[0]) {
|
||||
'.' => CommandType::DOT,
|
||||
'/' => CommandType::SLASH,
|
||||
'!' => CommandType::BANG,
|
||||
};
|
||||
} else {
|
||||
$this->command = null;
|
||||
$this->commandArgs = null;
|
||||
$this->commandType = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,18 @@
|
||||
namespace danog\MadelineProto\EventHandler;
|
||||
|
||||
use danog\MadelineProto\Ipc\IpcCapable;
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* Represents a generic update.
|
||||
*/
|
||||
abstract class Update extends IpcCapable
|
||||
abstract class Update extends IpcCapable implements JsonSerializable
|
||||
{
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
$v = \get_object_vars($this);
|
||||
unset($v['API'], $v['session']);
|
||||
$v['_'] = static::class;
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +116,16 @@ class Exception extends \Exception
|
||||
if ($maps !== '') {
|
||||
$maps = " ($maps)";
|
||||
}
|
||||
Logger::log("========= MANUAL SYSTEM ADMIN ACTION REQUIRED =========", Logger::FATAL_ERROR);
|
||||
Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR);
|
||||
Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR);
|
||||
Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR);
|
||||
Logger::log("The maximum number of mmap'ed regions was reached$maps: please increase the vm.max_map_count kernel config to 262144 to fix.");
|
||||
Logger::log("To fix, run the following command as root: echo 262144 | sudo tee /proc/sys/vm/max_map_count");
|
||||
Logger::log("To persist the change across reboots: echo vm.max_map_count=262144 | sudo tee /etc/sysctl.d/40-madelineproto.conf");
|
||||
Logger::log("On Windows and WSL, increasing the size of the pagefile might help; please switch to native Linux if the issue persists.");
|
||||
Logger::log("========= MANUAL SYSTEM ADMIN ACTION REQUIRED =========", Logger::FATAL_ERROR);
|
||||
Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR);
|
||||
Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR);
|
||||
Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR);
|
||||
}
|
||||
Logger::log($exception, Logger::FATAL_ERROR);
|
||||
die(1);
|
||||
|
@ -1544,6 +1544,13 @@ abstract class InternalDoc
|
||||
{
|
||||
$this->wrapper->getAPI()->stop();
|
||||
}
|
||||
/**
|
||||
* Converts a string into an async amphp stream.
|
||||
*/
|
||||
public static function stringToStream(string $str): \Amp\ByteStream\ReadableBuffer
|
||||
{
|
||||
return \danog\MadelineProto\Tools::stringToStream($str);
|
||||
}
|
||||
/**
|
||||
* Subscribe to event handler updates for a channel/supergroup we're not a member of.
|
||||
*
|
||||
|
@ -566,7 +566,7 @@ trait Files
|
||||
}
|
||||
$has_video = null;
|
||||
$has_animated = false;
|
||||
foreach ($media['attributes'] as $attr) {
|
||||
foreach ($media['document']['attributes'] as $attr) {
|
||||
$t = $attr['_'];
|
||||
if ($t === 'documentAttributeImageSize') {
|
||||
return new DocumentPhoto($this, $media, $attr);
|
||||
|
@ -135,10 +135,10 @@ trait UpdateHandler
|
||||
return;
|
||||
}
|
||||
if (\count($this->eventHandlerHandlers) !== 0 && \is_array($update)) {
|
||||
$update = $this->wrapUpdate($update);
|
||||
if ($update !== null) {
|
||||
$obj = $this->wrapUpdate($update);
|
||||
if ($obj !== null) {
|
||||
foreach ($this->eventHandlerHandlers as $closure) {
|
||||
$closure($update);
|
||||
$closure($obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user