Bot command arguments (if present) */ public readonly ?array $commandArgs; /** Whether this message is protected */ public readonly bool $protected; /** * @readonly * * @var list Regex matches, if a filter regex is present */ public ?array $matches = null; /** * Attached media. * * @var Audio|Document|DocumentPhoto|Gif|MaskSticker|Photo|RoundVideo|Sticker|Video|Voice|null */ public readonly ?Media $media; /** Whether this message is a sent scheduled message */ public readonly bool $fromScheduled; /** If the message was generated by an inline query, ID of the bot that generated it */ public readonly ?int $viaBotId; /** Last edit date of the message */ public readonly ?int $editDate; /** Inline or reply keyboard. */ public readonly InlineKeyboard|ReplyKeyboard|null $keyboard; /** Whether this message was [imported from a foreign chat service](https://core.telegram.org/api/import) */ public readonly bool $imported; /** For Public Service Announcement messages, the PSA type */ public readonly ?string $psaType; // Todo media (photosizes, thumbs), albums, reactions, replies, games eventually /** @internal */ public function __construct( MTProto $API, array $rawMessage, ) { parent::__construct($API, $rawMessage); $info = $this->API->getInfo($rawMessage); $this->entities = $rawMessage['entities'] ?? null; $this->message = $rawMessage['message']; $this->fromScheduled = $rawMessage['from_scheduled']; $this->viaBotId = $rawMessage['via_bot_id'] ?? null; $this->editDate = $rawMessage['edit_date'] ?? null; $this->keyboard = isset($rawMessage['reply_markup']) ? Keyboard::fromRawReplyMarkup($rawMessage['reply_markup']) : null; if (isset($rawMessage['fwd_from'])) { $fwdFrom = $rawMessage['fwd_from']; $this->fwdInfo = new ForwardedInfo( $fwdFrom['date'], isset($fwdFrom['from_id']) ? $this->API->getIdInternal($fwdFrom['from_id']) : null, $fwdFrom['from_name'] ?? null, $fwdFrom['channel_post'] ?? null, $fwdFrom['post_author'] ?? null, isset($fwdFrom['saved_from_peer']) ? $this->API->getIdInternal($fwdFrom['saved_from_peer']) : null, $fwdFrom['saved_from_msg_id'] ?? null ); $this->psaType = $fwdFrom['psa_type'] ?? null; } else { $this->fwdInfo = null; $this->psaType = null; } $this->protected = $rawMessage['noforwards']; $this->media = isset($rawMessage['media']) ? $API->wrapMedia($rawMessage['media'], $this->protected) : null; 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( ' ', \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; } } private readonly string $html; private readonly string $htmlTelegram; private readonly ?array $entities; /** * Get an HTML version of the message. * * @param bool $allowTelegramTags Whether to allow telegram-specific tags like tg-spoiler, tg-emoji, mention links and so on... */ public function getHTML(bool $allowTelegramTags = false): string { if (!$this->entities) { return \htmlentities($this->message); } if ($allowTelegramTags) { return $this->htmlTelegram ??= StrTools::entitiesToHtml($this->message, $this->entities, $allowTelegramTags); } return $this->html ??= StrTools::entitiesToHtml($this->message, $this->entities, $allowTelegramTags); } }