PHP code example of mohammad-zarifiyan / laravel-telegram-bot

1. Go to this page and download the library: Download mohammad-zarifiyan/laravel-telegram-bot library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mohammad-zarifiyan / laravel-telegram-bot example snippets




return [
    // The rest of your code

    'telegram' => [
        'api-key' => env('TELEGRAM_API_KEY'),
    ],
];



namespace App\Repositories;

use \MohammadZarifiyan\Telegram\Interfaces\ApiKeyRepository;

class TelegramApiKeyRepository implements ApiKeyRepository
{
    public function get(): ?string
    {
        return '123456:abcdefg';// Return API Key
    }
}



return [
    // The rest of the file

    'api-key-repository' => \App\Repositories\TelegramApiKeyRepository::class,// Set your own custom repository

    // The rest of the file
];



return [
    // The rest of your code

    'telegram' => [
        'endpoint' => env('TELEGRAM_ENDPOINT', 'https://api.telegram.org'),
    ],
];



namespace App\Repositories;

use \MohammadZarifiyan\Telegram\Interfaces\EndpointRepository;

class TelegramEndpointRepository implements EndpointRepository
{
    public function get(): ?string
    {
        return 'https://example.com';// Return your own custom endpoint
    }
}



return [
    // The rest of the file

    'endpoint-repository' => \App\Repositories\TelegramEndpointRepository::class,// Set your own custom repository

    // The rest of the file
];



return [
    // The rest of the file
    
    'verify-endpoint' => (bool) env('TELEGRAM_VERIFY_ENDPOINT', true),
    
    // The rest of the file
];



return [
    // The rest of the file
    
    'retry' => [
        'times' => 5,// How many times to retry requests in case of connection errors
        'sleep' => 200,// How long to sleep between retries in milliseconds
    ],
    
    // The rest of the file
];



return [
    // The rest of your code

    'telegram' => [
        'proxies' => explode(',', env('TELEGRAM_PROXIES', '')),
    ],
];



namespace App\Repositories;

use App\Models\TelegramProxy;
use Illuminate\Support\Collection;
use MohammadZarifiyan\Telegram\Interfaces\ProxyRepository;
use MohammadZarifiyan\Telegram\Proxy;

class TelegramProxyRepository implements ProxyRepository
{
    public function get(): Collection// Must return a collection of Proxy objects
    {
        return TelegramProxy::active()// Only get active proxies
            ->orderByDesc('score')// Sort by score
            ->get()
            ->toBase()
            ->map(fn (TelegramProxy $telegramProxy) => new Proxy(
                $this->telegramProxy->schema'://'.$this->telegramProxy->username.':'.$this->telegramProxy->password.'@'.$this->telegramProxy->hostname.':'.$this->telegramProxy->port,
                $telegramProxy->getKey(),
            ));
    }
}



return [
    // The rest of the file

    'proxy-repository' => \App\Repositories\TelegramProxyRepository::class,// Set your own custom repository

    // The rest of the file
];

use \MohammadZarifiyan\Telegram\Facades\Telegram;

$response = Telegram::perform('sendMessage', [
    'text' => 'Hello world!',
    'chat_id' => 1234
]);

echo $response->json('ok');// Reads ok value from the response

use \MohammadZarifiyan\Telegram\PendingTelegramRequestStack;
use \MohammadZarifiyan\Telegram\Facades\Telegram;
 
$responses = Telegram::concurrent(function (PendingTelegramRequestStack $stack) {
    $stack->add()
        ->setMethod('sendMessage')
        ->setData([
            'text' => 'Message 1',
            'chat_id' => 1234
        ]);

    $stack->add()
        ->setMethod('sendMessage')
        ->setData([
            'text' => 'Message 2',
            'chat_id' => 1234
        ]);

    $stack->add()
        ->setMethod('sendMessage')
        ->setData([
            'text' => 'Message 3',
            'chat_id' => 1234
        ]);
});

$result = $responses[0]->json('ok')
    && $responses[1]->json('ok')
    && $responses[2]->json('ok');

if ($result) {
    // All messages have been sent successfully.
}
else {
    // There was a problem sending some messages.
}

use \MohammadZarifiyan\Telegram\PendingTelegramRequestStack;
use \MohammadZarifiyan\Telegram\Facades\Telegram;
 
$responses = Telegram::concurrent(function (PendingTelegramRequestStack $stack) {
    $stack->add('first_message')
        ->setMethod('sendMessage')
        ->setData([
            'text' => 'Message 1',
            'chat_id' => 1234
        ]);

    $stack->add('second_message')
        ->setMethod('sendMessage')
        ->setData([
            'text' => 'Message 2',
            'chat_id' => 1234
        ]);

    $stack->add('third_message')
        ->setMethod('sendMessage')
        ->setData([
            'text' => 'Message 3',
            'chat_id' => 1234
        ]);
});

$result = $responses['first_message']->json('ok')
    && $responses['second_message']->json('ok')
    && $responses['third_message']->json('ok');

if ($result) {
    // All messages have been sent successfully.
}
else {
    // There was a problem sending some messages.
}

use MohammadZarifiyan\Telegram\PendingTelegramRequestBuilder;

$pendingTelegramRequestBuilder->setMethod(string $method): PendingTelegramRequestBuilder;
$pendingTelegramRequestBuilder->setData(array $data = []): PendingTelegramRequestBuilder;
$pendingTelegramRequestBuilder->setReplyMarkup(ReplyMarkup|string|null $replyMarkup = null): PendingTelegramRequestBuilder;
$pendingTelegramRequestBuilder->setApiKey(?string $apikey = null): PendingTelegramRequestBuilder;
$pendingTelegramRequestBuilder->setEndpoint(?string $endpoint = null): PendingTelegramRequestBuilder;

use Illuminate\Notifications\Notification;
use MohammadZarifiyan\Telegram\TelegramRequestOptions;

public function routeNotificationForTelegram(Notification $notification): null|string|int|TelegramRequestOptions
{
    // return an instance of TelegramRequestOptions
}

public function via($notifiable): array
{
    return ['telegram'];
}

public function toTelegram($notifiable)
{
    // Return an instance of \MohammadZarifiyan\Telegram\TelegramRequestContent
}

use App\Notifications\HelloNotification;
use App\Models\User;
use Illuminate\Support\Facades\Notification;

$users = User::all();

Notification::send($users, HelloNotification::class);



namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use MohammadZarifiyan\Telegram\TelegramRequestOptions;

class User extends Model
{
    use Notifiable;

    protected $fillable = ['telegram_id'];

    protected $casts = [
        'telegram_id' => 'integer'
    ];

    public function routeNotificationForTelegram(Notification $notification): null|string|int|TelegramRequestOptions
    {
        return TelegramRequestOptions::fresh()
            ->setRecipient($this->telegram_id)
            ->setApiKey('1234:abcd')// Optional: You can not call this method if you return an API key via the API Key Repository.
    }
}



namespace App\Notifications;

use \Illuminate\Notifications\Notification;
use \MohammadZarifiyan\Telegram\TelegramRequestContent;

class PaymentPaidNotification extends Notification
{
    public function via($notifiable): array
    {
        return ['telegram'];
    }

    public function toTelegram($notifiable)
    {
        $routeNotification = $notifiable->routeNotificationFor('telegram');

        return TelegramRequestContent::fresh()
            ->setMethod('sendMessage')
            ->setData([
                'text' => 'Hello',
                'chat_id' => $routeNotification->recipient
            ]);
    }
}



namespace App\Telegram\ReplyMarkups;

use \MohammadZarifiyan\Telegram\Interfaces\ReplyMarkup;

class MyKeyboard implements ReplyMarkup
{
    public function __invoke(): array
    {
        return [
            'resize_keyboard' => true,
            'keyboard' => [
                [
                    // This array contains a row
                    
                    [
                        // This array contains a column
                        'text' => 'top left button'
                    ],
                    
                    [
                        // This array contains a column
                        'text' => 'top right button'
                    ]
                ],
                [
                    // This array contains a row
                    
                    [
                        // This array contains a column
                        'text' => 'bottom left button'
                    ],
                    
                    [
                        // This array contains a column
                        'text' => 'bottom right button'
                    ]
                ]
            ]
        ];
    }
}

use \App\Telegram\ReplyMarkups\MyKeyboard;
use \MohammadZarifiyan\Telegram\Facades\Telegram;

Telegram::perform(
    'sendMessage',
    [
        'text' => 'Hello world!',
        'chat_id' => 1234
    ],
    MyKeyboard::class
);



namespace App\Notifications;

use \App\Telegram\ReplyMarkups\MyKeyboard;
use \Illuminate\Notifications\Notification;
use \MohammadZarifiyan\Telegram\TelegramRequestContent;

class PaymentPaidNotification extends Notification
{
    public function via($notifiable): array
    {
        return ['telegram'];
    }

    public function toTelegram($notifiable)
    {
        $routeNotification = $notifiable->routeNotificationFor('telegram');

        return TelegramRequestContent::fresh()
            ->setMethod('sendMessage')
            ->setData([
                'text' => 'Hello',
                'chat_id' => $routeNotification->recipient
            ])
            ->setReplyMarkup(MyKeyboard::class); 
    }
}

use MohammadZarifiyan\Telegram\Attachment;
use MohammadZarifiyan\Telegram\Facades\Telegram;

$fileContents = file_get_contents('path/to/file.png');
$fileName = 'my-file.png';

Telegram::perform('sendPhoto', [
    'photo' => new Attachment($fileContents, $fileName),
    'chat_id' => 1234
]);



return [
    // The rest of the file
    
    'pending-http-request-manipulator' => App\Telegram\PendingHttpRequestManipulator::class,
    
    // The rest of the file
];



namespace App\Telegram;

use MohammadZarifiyan\Telegram\Interfaces\PendingHttpRequest as PendingHttpRequestInterface;

class PendingHttpRequestManipulator implements PendingHttpRequestInterface
{
    public function __construct(public PendingHttpRequestInterface $pendingHttpRequest)
    {
        //
    }
    
    public function getUrl(): string
    {
        return $this->pendingHttpRequest->getUrl();// You can change the URL of the request here.
    }
    
    public function getBody(): array
    {
        return $this->pendingHttpRequest->getBody();// You can change the body of the request here.
    }
    
    public function getAttachments(): array
    {
        return $this->pendingHttpRequest->getAttachments();// You can change the attachments of the request here.
    }
}

use MohammadZarifiyan\Telegram\Facades\Telegram;

$response = Telegram::perform('getFile', [
    'file_id' => 'abcdefg'// Your file id
]);

if ($response->json('ok')) {
    $filePath = $response->json('result.file_path');
    $fileUrl = Telegram::generateFileUrl($filePath);
    // You can use $fileUrl to download the file.
}
else {
    $error = $response->json('description');
    // There was an error receiving file information. You can use $error to display the error.
}

use MohammadZarifiyan\Telegram\Facades\Telegram;

$apiKey = '123456:abcdefg';
$parsedApiKey Telegram::getBotId($apiKey);

echo $parsedApiKey->botId;// Output: 123456
echo $parsedApiKey->botTokenHash;// Output: abcdefg

use MohammadZarifiyan\Telegram\Facades\Telegram;

echo Telegram::getBotId();// Output: 123456

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use \MohammadZarifiyan\Telegram\Facades\Telegram;

Route::get('telegram/login', function (Request $request) {
    $isValid = Telegram::validateAuthorizationData($request->all());
    
    if ($isValid) {
        $user = User::firstOrCreate([
            'telegram_id' => $request->query('id')
        ]);
        
        Auth::login($user);

        return 'Success: You are logged into your account!';
    }
    else {
        return 'Error: Telegram authorization data is not valid!';
    }
});



namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $fillable = ['telegram_id'];

    protected $casts = [
        'telegram_id' => 'integer',
    ];
}



return [
    // The rest of your code

    'telegram' => [
        'public-key-hex' => env('TELEGRAM_PUBLIC_KEY_HEX'),
    ],
];



return [
    // The rest of your code

    'telegram' => [
        'secret-token' => env('TELEGRAM_SECRET_TOKEN'),
    ],
];



namespace App\Repositories;

use MohammadZarifiyan\Telegram\Interfaces\SecretTokenRepository;

class TelegramSecretTokenRepository implements SecretTokenRepository
{
    public function get(): ?string
    {
        return 'abcdefg';// Return your secret token
    }
}



return [
    // The rest of the file

    'secret-token-repository' => \App\Repositories\TelegramSecretTokenRepository::class,// Set your own custom repository

    // The rest of the file
];



use MohammadZarifiyan\Telegram\Facades\Telegram;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('telegram-update', function (Request $request) {
   Telegram::handleRequest($request);
});



return [
    // The rest of the file

    'middlewares' => [
        App\Telegram\Middlewares\YourMiddleware::class,
    ],
    
    // The rest of the file
];



return [
    // The rest of the file

    'command_handlers' => [
        App\Telegram\CommandHandlers\YourCommandHandler::class,
    ],
    
    // The rest of the file
];



namespace App\Telegram\CommandHandlers;

use MohammadZarifiyan\Telegram\Enums\Signal;
use MohammadZarifiyan\Telegram\Interfaces\CommandHandler;
use MohammadZarifiyan\Telegram\Update;

class StartCommandHandler implements CommandHandler
{
    /**
     * The signature(s) of the Telegram bot command that can be handled by current CommandHandler.
     *
     * @param Update $update
     * @return string|array
     */
    public function getSignature(Update $update): string|array
    {
        return 'start';
    }
    
    /**
     * Handles the Telegram command.
     *
     * @param Update $update
     * @return Signal
     */
    public function handle(Update $update): Signal
    {
        if (true) {// update can be handled
            // Handle command here

            return Signal::Exit;
        }
        else {
            return Signal::Continue;
        }
    }
}

$command = $update->toCommand();

$command->signature; // Returns 'start'
$command->value; // Returns 'abc'



namespace App\Telegram\CommandHandlers;

use MohammadZarifiyan\Telegram\Enums\Signal;
use MohammadZarifiyan\Telegram\Interfaces\AnonymousCommandHandler;
use MohammadZarifiyan\Telegram\Update;

class MyAnonymousCommandHandler implements AnonymousCommandHandler
{
    /**
     * Checks whether the current CommandHandler can process the command.
     *
     * @param Update $update
     * @return bool
     */
    public function matchesSignature(Update $update): bool
    {
        $command = $update->toCommand();
        
        return $command->signature === 'start';
    }
    
    /**
     * Handles the Telegram command.
     *
     * @param Update $update
     * @return Signal
     */
    public function handle(Update $update): Signal
    {
        if (true) {// update can be handled
            // Handle command here

            return Signal::Exit;
        }
        else {
            return Signal::Continue;
        }
    }
}



return [
    // The rest of the file

    'breakers' => [
        App\Telegram\Breakers\YourBreaker::class,
    ],
    
    // The rest of the file
];



namespace App\Telegram\Breakers;

use MohammadZarifiyan\Enums\Signal;
use MohammadZarifiyan\Telegram\Update;

class CancelBulkNotificationBreaker
{
   public function handleCallbackQuery(Update $update): Signal
   {
      if ($update->input('callback_query.data') === 'cancel-sending-all-notifications') {
         /*
          * Cancel sending notifications
          * 
          * Stop processing request by other Telegram breakers,
          * Because we already handled the Update and the is no need to continue processing this Update in our application
          */
         return Signal::Exit;
      }
      else {
         /*
          * Continue processing the Telegram Update using other Telegram Breakers or Telegram Stages,
          * Because this Telegram breaker could was not able to handle the Telegram update
          */
         return Signal::Continue;
      }
   }
}



return [
    // The rest of the file

    'gainer-resolver' => \App\Telegram\GainerResolver::class,// Set your own class name

    // The rest of the file
];



namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $fillable = ['telegram_id'];

    protected $casts = [
        'telegram_id' => 'integer',
    ];
}



use App\Models\User;
use MohammadZarifiyan\Telegram\Update;
use MohammadZarifiyan\Telegram\Interfaces\GainerResolver as GainerResolverInterface;

class GainerResolver implements GainerResolverInterface
{
    public function handle(Update $update)
    {
        if ($update->type() === 'message') {
            return User::firstOrCreate([
                'telegram_id' => $update->input('message.from.id')
            ]);
        }
        
        return null;
    }
}

use MohammadZarifiyan\Telegram\Facades\Telegram;
use App\Models\User;

$update = Telegram::getUpdate();
$gainer = $update->gainer();

if ($gainer instanceof User) {
    echo 'The user became a member of the bot on date ' . $gainer->created_at;
}
else {
    echo 'The $gainer value is null.';
}



use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('telegram_id');
            $table->string('stage')->nullable();
            $table->unsignedTinyInteger('age')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};



namespace App\Models;

use MohammadZarifiyan\Telegram\Interfaces\HasStage;
use Illuminate\Database\Eloquent\Model;

class User extends Model implements HasStage
{
    protected $fillable = [
        'telegram_id',
        'age',
        'stage',
    ];

    protected $casts = [
        'telegram_id' => 'integer',
        'age' => 'integer',
    ];

    public function getStage(): null|string|object
    {
        return $this->stage;
    }
}



namespace App\Telegram\Stages;

use App\Telegram\Updates\AgeUpdate;
use MohammadZarifiyan\Telegram\Facades\Telegram;

class Age
{
    public function handleMessage(AgeUpdate $update): void
    {
        $update->gainer()->update([
            'stage' => null,
            'age' => $update->integer('message.text')
        ]);
        
        Telegram::perform('sendMessage', [
            'text' => 'Your age has been saved in the database.',
            'chat_id' => $update->integer('message.chat.id'),
        ]);
    }
}



namespace App\Telegram\Updates;

use MohammadZarifiyan\Telegram\FormUpdate;

class AgeUpdate extends FormUpdate
{
    public function rules(): array
    {
        return [
            'message.text' => ['bail', '

use MohammadZarifiyan\Telegram\Facades\Telegram;
use App\Telegram\Stages\Age;

$gainer = Telegram::getUpdate()->gainer();
$gainer->update(['stage' => Age::class]);

Telegram::perform('sendMessage', [
    'chat_id' => $gainer->telegram_id,
    'text' => 'How old are you?'
]);

$faker = \Faker\Factory::create();
$apiKey = $faker->telegramBotApiKey();

use MohammadZarifiyan\Telegram\Facades\Telegram;
use MohammadZarifiyan\Telegram\PendingTelegramRequest;
use Illuminate\Http\Client\Response;

Telegram::fake();

Telegram::perform('sendMessage', [
    'chat_id' => 123,
    'text' => 'Hello World!'
]);

Telegram::assertSent(function (PendingTelegramRequest $pendingTelegramRequest, Response $response) {
    $pendingTelegramRequest->apiKey;// The API Key that used for request
    $pendingTelegramRequest->endpoint;// The endpoint that used for request
    $pendingTelegramRequest->method;// The method that used for request (sendMessage)
    $pendingTelegramRequest->data;// The data that sent to Telegram API (['chat_id' => 123, 'text' => 'Hello World!']])
    $pendingTelegramRequest->replyMarkup;
    
    return true;// return true if the $pendingTelegramRequest matches your expected request
});

use MohammadZarifiyan\Telegram\Facades\Telegram;
use MohammadZarifiyan\Telegram\Promise;

Telegram::fake([
    Promise::on('sendMessage')
        ->onlyApiKeys('123:abcdefg')
        ->setStatusCode(400)
        ->body([
            'ok' => false,
            'message' => 'Your message cannot be delivered.'
        ]),
]);

$response = Telegram::fresh('123:abcdefg')->perform('sendMessage', [
    'chat_id' => 44444,
    'message' => 'Hello World!'
]);

$response->json('ok');// returns false
$response->json('message');// returns 'Your message cannot be delivered.'

Telegram::fake(...);
Telegram::assertSent(...);
Telegram::assertSentInOrder(...);
Telegram::assertNotSent(...);
Telegram::assertNothingSent();
Telegram::assertSentCount(...);
shell
php artisan vendor:publish --provider="MohammadZarifiyan\Telegram\Providers\InstantServiceProvider" --tag="telegram-config"
shell
php artisan make:telegram-reply-markup <ReplyMarkupName>
shell
php artisan make:telegram-reply-markup MyKeyboard
bash
php artisan make:telegram-middleware <MiddlewareName>
bash
php artisan make:telegram-breaker <BreakerName>
shell
php artisan make:telegram-stage <StageName>