Message Events
Message events represent incoming or outgoing messages in chats, channels, and private conversations.
Message Class
The Message class represents a Telegram message with all its properties and methods.
Properties
Bot command if present (e.g., “start” from “/start”)
Bot command arguments if present
Whether this message is protected from forwarding
Regex matches if a filter regex is present
All regex matches if a filter multiple match regex is present
Attached media (Audio, Document, Photo, Video, Voice, Sticker, etc.)
Whether this is a sent scheduled message
ID of the bot that generated the message (for inline queries)
Last edit date of the message (Unix timestamp)
Whether the edit is hidden (non-content changes like reactions)
keyboard
InlineKeyboard|ReplyKeyboard|null
Inline or reply keyboard attached to the message
Whether message was imported from a foreign chat service
For Public Service Announcement messages, the PSA type
View counter for channel messages
Forward counter for channel messages
Author signature if enabled for channel messages
Message entities for styled text (bold, italic, links, etc.)
Group ID for albums (all messages in same album have identical ID)
The poll attached to the message
Information about forwarded message
List of our message reactions
Whether this is a scheduled message
Handling Messages
Basic Handler
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\EventHandler\Message;
class MyBot extends EventHandler
{
public function onUpdateNewMessage(Message $message): void
{
$text = $message->message;
$this->logger("Received: $text");
}
}
With SimpleEventHandler and Filters
use danog\MadelineProto\SimpleEventHandler;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Attributes\Handler;
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
class MyBot extends SimpleEventHandler
{
#[Handler]
#[Incoming]
public function handleIncoming(Message $message): void
{
// Only processes incoming messages
$this->logger("Incoming: {$message->message}");
}
}
Message Methods
reply
Reply to the message.
Parse mode for formatting (Markdown, HTML, etc.)
Schedule message for future sending (Unix timestamp)
Send silently (no notification)
$message->reply("Hello! You said: {$message->message}");
// With formatting
$message->reply(
"**Bold** and _italic_ text",
parseMode: ParseMode::MARKDOWN
);
// With keyboard
$message->reply("Choose an option:", replyMarkup: [
'inline_keyboard' => [[
['text' => 'Option 1', 'callback_data' => 'opt1'],
['text' => 'Option 2', 'callback_data' => 'opt2'],
]]
]);
delete
Delete the message.
Whether to delete for all users (requires permissions)
edit
Edit the message text.
Parse mode for formatting
$message->edit("Updated message text");
forward
Forward the message to another chat.
Destination chat (username or ID)
$message->forward('@channel');
$message->forward(123456789);
pin
Pin the message in the chat.
Whether to pin only for yourself in PM
Pin silently (no notification)
unpin
Unpin the message.
Command Handling
use danog\MadelineProto\EventHandler\Message;
public function onUpdateNewMessage(Message $message): void
{
if ($message->command === 'start') {
$message->reply("Welcome!");
}
if ($message->command === 'echo' && $message->commandArgs) {
$text = implode(' ', $message->commandArgs);
$message->reply($text);
}
}
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Media\Photo;
use danog\MadelineProto\EventHandler\Media\Document;
public function onUpdateNewMessage(Message $message): void
{
if ($message->media instanceof Photo) {
$this->logger("Received a photo");
// Download the photo
$info = $message->media->download();
}
if ($message->media instanceof Document) {
$this->logger("Received a document: {$message->media->fileName}");
}
}
Regex Matching
use danog\MadelineProto\SimpleEventHandler;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Filter\FilterRegex;
class MyBot extends SimpleEventHandler
{
#[FilterRegex('/\/echo (.+)/')]
public function onEcho(Message $message): void
{
$text = $message->matches[1];
$message->reply($text);
}
#[FilterRegex('/hello|hi/i')]
public function onGreeting(Message $message): void
{
$message->reply("Hello there!");
}
}
Entity Processing
use danog\MadelineProto\EventHandler\Message;
public function onUpdateNewMessage(Message $message): void
{
foreach ($message->entities as $entity) {
if ($entity->type === 'url') {
$url = substr($message->message, $entity->offset, $entity->length);
$this->logger("Found URL: $url");
}
}
}
Update Types
New Messages
public function onUpdateNewMessage(Message $message): void
{
// Handle new messages in private chats and groups
}
New Channel Messages
public function onUpdateNewChannelMessage(Message $message): void
{
// Handle new messages in channels
}
Edited Messages
public function onUpdateEditMessage(Message $message): void
{
// Handle edited messages
$this->logger("Message edited at: {$message->editDate}");
}
Edited Channel Messages
public function onUpdateEditChannelMessage(Message $message): void
{
// Handle edited channel messages
}
Complete Example
use danog\MadelineProto\SimpleEventHandler;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Attributes\Handler;
use danog\MadelineProto\EventHandler\SimpleFilter\{Incoming, HasMedia};
use danog\MadelineProto\EventHandler\Filter\FilterRegex;
use danog\MadelineProto\ParseMode;
class EchoBot extends SimpleEventHandler
{
#[FilterRegex('/^\/start/')]
#[Incoming]
public function handleStart(Message $message): void
{
$message->reply(
"**Welcome to Echo Bot!**\n\n" .
"Commands:\n" .
"/echo <text> - Echo your message\n" .
"/info - Get message info",
parseMode: ParseMode::MARKDOWN
);
}
#[FilterRegex('/^\/echo (.+)/')]
public function handleEcho(Message $message): void
{
$text = $message->matches[1];
$message->reply($text);
}
#[FilterRegex('/^\/info/')]
public function handleInfo(Message $message): void
{
$info = [
"Message ID: {$message->id}",
"From: {$message->senderId}",
"Date: " . date('Y-m-d H:i:s', $message->date),
];
if ($message->editDate) {
$info[] = "Edited: " . date('Y-m-d H:i:s', $message->editDate);
}
$message->reply(implode("\n", $info));
}
#[Handler]
#[HasMedia]
public function handleMedia(Message $message): void
{
$type = get_class($message->media);
$message->reply("Received media: " . basename($type));
}
}
EchoBot::startAndLoopBot('bot.madeline', 'YOUR_BOT_TOKEN');
See Also