Documentation Index Fetch the complete documentation index at: https://mintlify.com/danog/MadelineProto/llms.txt
Use this file to discover all available pages before exploring further.
Message Types
MadelineProto provides typed message classes for different chat types:
Message - Base message class
PrivateMessage - Messages in private chats
GroupMessage - Messages in groups
ChannelMessage - Messages in channels
SecretMessage - Messages in secret chats
Receiving Messages
Handle incoming messages using event handlers with type filters:
use danog\MadelineProto\EventHandler\Attributes\ Handler ;
use danog\MadelineProto\EventHandler\ Message ;
use danog\MadelineProto\EventHandler\SimpleFilter\ Incoming ;
use danog\MadelineProto\ SimpleEventHandler ;
class MyBot extends SimpleEventHandler
{
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Message properties
$text = $message -> message ; // Message text
$chatId = $message -> chatId ; // Chat ID
$senderId = $message -> senderId ; // Sender ID
$messageId = $message -> id ; // Message ID
$date = $message -> date ; // Unix timestamp
$replyToId = $message -> replyToMsgId ; // Reply to message ID
$this -> logger ( "Got message: $text from $senderId " );
}
}
Sending Text Messages
Using the Reply Method
The simplest way to respond to a message:
use danog\MadelineProto\ ParseMode ;
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Simple reply
$message -> reply ( "Hello!" );
// Reply with Markdown
$message -> reply (
message : "**Bold** and *italic* text" ,
parseMode : ParseMode :: MARKDOWN
);
// Reply with HTML
$message -> reply (
message : "<b>Bold</b> and <i>italic</i> text" ,
parseMode : ParseMode :: HTML
);
// Reply silently (no notification)
$message -> reply (
message : "Silent message" ,
silent : true
);
// Reply without webpage preview
$message -> reply (
message : "Check https://example.com" ,
noWebpage : true
);
}
Using sendMessage Method
Send messages to any chat:
public function sendToUser ( int $userId ) : void
{
$this -> sendMessage (
peer : $userId ,
message : "Hello from MadelineProto!" ,
parseMode : ParseMode :: TEXT
);
}
public function sendToChannel () : void
{
$this -> sendMessage (
peer : '@myChannel' ,
message : "New post in channel" ,
parseMode : ParseMode :: MARKDOWN
);
}
Advanced Message Options
$message -> reply (
message : "Advanced message" ,
parseMode : ParseMode :: MARKDOWN ,
replyMarkup : $keyboard , // Add keyboard
sendAs : '@myChannel' , // Send as specific peer
scheduleDate : time () + 3600 , // Schedule for 1 hour later
silent : true , // Silent message
noForwards : true , // Disable forwarding
background : false , // Don't send as background
clearDraft : true , // Clear draft
updateStickersetsOrder : false , // Don't reorder stickersets
cancellation : $cancellation // Cancellation token
);
Message Entities
MadelineProto automatically parses message entities:
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Access parsed entities
foreach ( $message -> entities as $entity ) {
// Entity types: Bold, Italic, Code, Pre, Url, Mention, etc.
$this -> logger ( "Entity type: " . $entity :: class );
}
}
Available Entity Types
Bold - Bold text
Italic - Italic text
Code - Inline code
Pre - Code blocks
Url - URLs
Mention - @username mentions
Hashtag - #hashtag
BotCommand - /command
Email - Email addresses
Phone - Phone numbers
CustomEmoji - Custom emojis
Editing Messages
Edit sent messages:
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
$sent = $message -> reply ( "Initial message" );
// Edit the sent message
$this -> editMessage (
peer : $sent -> chatId ,
id : $sent -> id ,
message : "Edited message" ,
parseMode : ParseMode :: TEXT
);
}
Deleting Messages
Delete messages from chats:
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Delete this message
$message -> delete (
revoke : true // Delete for all participants
);
// Delete specific messages
$this -> deleteMessages (
peer : $message -> chatId ,
id : [ 1 , 2 , 3 ], // Message IDs to delete
revoke : true
);
}
Replying to Messages
Check and get replied-to messages:
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Check if message is a reply
if ( $message -> isReply ()) {
// Get the replied-to message
$repliedTo = $message -> getReply ();
if ( $repliedTo ) {
$message -> reply ( "You replied to: " . $repliedTo -> message );
}
}
// Get reply of specific type
$repliedPhoto = $message -> getReply ( Message :: class );
}
Forwarding Messages
Forward messages between chats:
public function forwardMessage ( Message $message ) : void
{
$this -> forwardMessages (
from_peer : $message -> chatId ,
to_peer : '@myChannel' ,
id : [ $message -> id ],
drop_author : false , // Keep original author
drop_media_captions : false
);
}
Message Filters
Use filters to handle specific messages:
use danog\MadelineProto\EventHandler\Filter\ FilterCommand ;
use danog\MadelineProto\EventHandler\Filter\ FilterText ;
use danog\MadelineProto\EventHandler\Filter\ FilterRegex ;
use danog\MadelineProto\EventHandler\SimpleFilter\ FromAdmin ;
// Handle /start command
#[ FilterCommand ( 'start' )]
public function startCommand ( Message $message ) : void
{
$message -> reply ( "Welcome! Use /help for commands." );
}
// Handle specific text
#[ FilterText ( 'hello' )]
public function helloText ( Message $message ) : void
{
$message -> reply ( "Hi there!" );
}
// Handle regex patterns
#[ FilterRegex ( '/. * (help|support). * /i' )]
public function helpRegex ( Message $message ) : void
{
$message -> reply ( "How can I help you?" );
}
// Only from admins
#[ FilterCommand ( 'admin' )]
public function adminCommand ( Message & FromAdmin $message ) : void
{
$message -> reply ( "Admin command executed." );
}
Command Handling
MadelineProto automatically parses bot commands:
#[ FilterCommand ( 'echo' )]
public function echoCommand ( Message $message ) : void
{
// Access command arguments
$args = $message -> commandArgs ;
if ( empty ( $args )) {
$message -> reply ( "Usage: /echo <text>" );
return ;
}
$message -> reply ( $args [ 0 ]);
}
#[ Handler ]
public function handleCommands ( Incoming & Message $message ) : void
{
if ( $message -> command ) {
$this -> logger ( "Command: { $message -> command }" );
$this -> logger ( "Type: { $message -> commandType -> value }" );
$this -> logger ( "Args: " . implode ( ', ' , $message -> commandArgs ?? []));
}
}
Typing Indicators
Show typing indicators:
use danog\MadelineProto\EventHandler\Action\ Typing ;
use danog\MadelineProto\EventHandler\Action\ RecordVideo ;
use danog\MadelineProto\EventHandler\Action\ UploadPhoto ;
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Show "typing..." indicator
$message -> setAction ( new Typing );
// Simulate processing
sleep ( 2 );
$message -> reply ( "Processed!" );
}
Reading Messages
Mark messages as read:
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Mark this message as read
$message -> read ();
// Mark all messages in chat as read
$message -> read ( readAll : true );
}
Message Properties
All available message properties:
#[ Handler ]
public function handleMessage ( Incoming & Message $message ) : void
{
// Basic properties
$id = $message -> id ; // Message ID
$text = $message -> message ; // Message text
$chatId = $message -> chatId ; // Chat ID
$senderId = $message -> senderId ; // Sender ID
$date = $message -> date ; // Unix timestamp
// Message flags
$isOut = $message -> out ; // Is outgoing?
$isMentioned = $message -> mentioned ; // Were we mentioned?
$isSilent = $message -> silent ; // Is silent?
$isProtected = $message -> protected ; // Is protected (no forward)?
$isScheduled = $message -> scheduled ; // Is scheduled?
// Reply information
$replyToId = $message -> replyToMsgId ; // Reply to message ID
$isReply = $message -> isReply (); // Is a reply?
// Thread/topic information
$topicId = $message -> topicId ; // Forum topic ID
$threadId = $message -> threadId ; // Thread ID
// Media and extras
$media = $message -> media ; // Attached media
$keyboard = $message -> keyboard ; // Inline/reply keyboard
$entities = $message -> entities ; // Message entities
// Channel-specific
$views = $message -> views ; // View count
$forwards = $message -> forwards ; // Forward count
$signature = $message -> signature ; // Post signature
// Forward information
$fwdInfo = $message -> fwdInfo ; // Forwarded info
// Edit information
$editDate = $message -> editDate ; // Last edit timestamp
}
Working with Channels
use danog\MadelineProto\EventHandler\Message\ ChannelMessage ;
#[ Handler ]
public function handleChannelMessage ( Incoming & ChannelMessage $message ) : void
{
// Get discussion (comments)
$discussion = $message -> getDiscussion ();
// Reply in discussion
if ( $discussion ) {
$discussion -> reply ( "Interesting post!" );
}
// Access channel-specific properties
$views = $message -> views ;
$signature = $message -> signature ;
}
Best Practices
Always handle FLOOD_WAIT errors: try {
$message -> reply ( "Response" );
} catch ( \danog\MadelineProto\ RPCErrorException $e ) {
if ( $e -> rpc === 'FLOOD_WAIT_X' ) {
// Wait and retry
}
}
Choose the right parse mode:
ParseMode::TEXT - No formatting, safe for user input
ParseMode::MARKDOWN - Markdown syntax
ParseMode::HTML - HTML tags
Always validate message content: if ( strlen ( $message -> message ) > 4096 ) {
$message -> reply ( "Message too long!" );
return ;
}