Use this file to discover all available pages before exploring further.
MadelineProto provides full support for Telegram’s VoIP (Voice over IP) calls, allowing you to make and receive voice calls, play audio files, and even stream audio content.
$call->callID; // int - Phone call ID$call->outgoing; // bool - Whether call is outgoing$call->otherID; // int - ID of other user in call$call->date; // int - When call was created
use danog\MadelineProto\EventHandler\Attributes\Handler;use danog\MadelineProto\EventHandler\Filter\FilterCommand;use danog\MadelineProto\EventHandler\Message;use danog\MadelineProto\RemoteUrl;use danog\MadelineProto\LocalFile;class MyBot extends SimpleEventHandler{ #[FilterCommand('call')] public function makeCall(Message $message): void { // Request a call to a user $call = $this->requestCall($message->senderId); // Play audio file $call->play(new RemoteUrl('http://example.com/audio.mp3')); $message->reply("Calling user..."); }}
#[FilterCommand('call')]public function callWithAudio(Message $message): void{ $call = $this->requestCall($message->senderId); // Play local audio file $call->play(new LocalFile('/path/to/music.mp3'));}
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;#[Handler]public function handleIncomingCall(Incoming&VoIP $call): void{ $this->logger("Incoming call from {$call->otherID}"); // Accept the call $call->accept(); // Play audio $call->play(new RemoteUrl('http://example.com/greeting.mp3'));}
public function setHoldMusic(VoIP $call): void{ // Music to play when call is on hold $call->playOnHold( new LocalFile('hold1.mp3'), new LocalFile('hold2.mp3'), new LocalFile('hold3.mp3') );}
public function controlPlayback(VoIP $call): void{ // Start playing $call->play(new LocalFile('long-audio.mp3')); // Pause playback $call->pause(); // Check if paused if ($call->isPaused()) { $this->logger("Playback is paused"); } // Resume playback $call->resume();}
use danog\MadelineProto\LocalFile;public function recordCall(VoIP $call): void{ // Record incoming audio to file (OGG OPUS format) $call->setOutput(new LocalFile('/tmp/recording.ogg'));}
use Amp\ByteStream\WritableStream;public function recordToStream(VoIP $call, WritableStream $output): void{ // Write incoming OPUS packets to stream $call->setOutput($output);}
use danog\MadelineProto\VoIP\DiscardReason;public function endCall(VoIP $call): void{ // Hang up $call->discard(DiscardReason::HANGUP); // Hang up with rating $call->discard( reason: DiscardReason::HANGUP, rating: 5, // 1-5 stars comment: "Great call quality!" );}
use danog\MadelineProto\VoIP\DiscardReason;// Available discard reasons:DiscardReason::HANGUP; // Normal hangupDiscardReason::MISSED; // Missed callDiscardReason::DISCONNECT; // DisconnectedDiscardReason::BUSY; // User busy
use danog\MadelineProto\EventHandler\SimpleFilter\HasAudio;use danog\MadelineProto\EventHandler\Message\PrivateMessage;// Play incoming audio messages in a call#[Handler]public function playAudioMessage(Incoming&PrivateMessage&HasAudio $message): void{ // Request call to sender $call = $this->requestCall($message->senderId); // Play the audio from the message $call->play($message->media->getStream());}
class IVRBot extends SimpleEventHandler{ #[Handler] public function handleIVR(Incoming&VoIP $call): void { $call->accept() ->play(new LocalFile('welcome.mp3')) ->then(new LocalFile('menu.mp3')) ->playOnHold(new LocalFile('hold-music.mp3')); // Set timeout to end call $this->scheduleCallEnd($call, 300); // 5 minutes }}
use danog\MadelineProto\Settings;use danog\MadelineProto\Settings\VoIP as VoIPSettings;$settings = new Settings;$voip = $settings->getVoip();// Configure VoIP settings (if needed)// Most settings are automatic
use danog\MadelineProto\SimpleEventHandler;use danog\MadelineProto\VoIP;class CallBot extends SimpleEventHandler{ #[Handler] public function onIncomingCall(Incoming&VoIP $call): void { $this->logger("📞 Incoming call from {$call->otherID}"); // Accept and greet $call->accept() ->play(new LocalFile('hello.mp3')) ->then(new LocalFile('menu.mp3')); // Set hold music $call->playOnHold( new RemoteUrl('https://example.com/hold1.mp3'), new RemoteUrl('https://example.com/hold2.mp3') ); // Get verification emojis $emojis = $call->getVisualization(); if ($emojis) { $this->logger("Verify: " . implode(' ', $emojis)); } // Record call $call->setOutput( new LocalFile("/recordings/{$call->callID}.ogg") ); }}