hugphp / telegram
A Laravel package for interacting with the Telegram Bot API
Fund package maintenance!
nunomaduro
Patreon
www.paypal.com/paypalme/enunomaduro
Requires
- php: ^8.3.0
- illuminate/support: ^11.0|^12.0
Requires (Dev)
- laravel/pint: ^1.18.1
- orchestra/testbench: ^10.2
- peckphp/peck: ^0.1.1
- pestphp/pest: ^3.5.1
- pestphp/pest-plugin-type-coverage: ^3.1
- phpstan/phpstan: ^1.12.7
- rector/rector: ^1.2.8
- symfony/var-dumper: ^7.1.6
README
HugPHP Telegram
A robust and type-safe Laravel package for interacting with the Telegram Bot API. This package provides a simple, performant, and flexible interface for sending messages, media, locations, contacts, and managing webhooks in your Laravel applications.
Features
- Type-Safe: Built with strict typing and validated by PHPStan for 100% type safety.
- Easy Integration: Seamlessly integrates with Laravel’s HTTP client and configuration system.
- Comprehensive API Support: Send messages, photos, videos, documents, locations, contacts, and manage webhooks.
- Retry Logic: Configurable retries and timeouts for reliable API communication.
- Tested: >83% test coverage with Pest, ensuring reliability and stability.
Feature Roadmap
Feature | Method | Status |
---|---|---|
Send Message | sendMessage |
✅ Completed |
Send Photo | sendPhoto |
✅ Completed |
Send Video | sendVideo |
✅ Completed |
Send Document | sendDocument |
✅ Completed |
Send Location | sendLocation |
✅ Completed |
Send Contact | sendContact |
✅ Completed |
Set Webhook | setWebhook |
✅ Completed |
Get Webhook Info | getWebhookInfo |
✅ Completed |
Delete Webhook | deleteWebhook |
✅ Completed |
Get Updates | getUpdates |
✅ Completed |
Handle Callback Query | handleCallbackQuery |
☐ Pending |
File Uploads | fileUploads |
☐ Pending |
Send Notification | sendNotification |
☐ Pending |
Installation
Install the package via Composer:
composer require hugphp/telegram
Publish the configuration file:
php artisan vendor:publish --provider="HugPHP\Telegram\TelegramServiceProvider"
This creates a config/telegram.php
file for configuring your Telegram bot settings.
Configuration
Edit config/telegram.php
to set your bot token and other settings:
return [ 'bot_token' => env('TELEGRAM_BOT_TOKEN', 'your-bot-token'), 'default_chat_id' => env('TELEGRAM_DEFAULT_CHAT_ID', '68*****41'), 'api_base_url' => env('TELEGRAM_API_BASE_URL', 'https://api.telegram.org'), 'webhook_url' => env('TELEGRAM_WEBHOOK_URL', 'https://your-app.com/telegram/webhook'), 'webhook_max_connections' => env('TELEGRAM_WEBHOOK_MAX_CONNECTIONS', 40), 'webhook_allowed_updates' => env('TELEGRAM_WEBHOOK_ALLOWED_UPDATES', []), 'http_timeout' => env('TELEGRAM_HTTP_TIMEOUT', 10), 'http_retries' => env('TELEGRAM_HTTP_RETRIES', 3), 'http_retry_delay' => env('TELEGRAM_HTTP_RETRY_DELAY', 500), ];
Add the following to your .env
file:
TELEGRAM_BOT_TOKEN=your-bot-token-from-botfather TELEGRAM_DEFAULT_CHAT_ID=68*****41 TELEGRAM_WEBHOOK_URL=https://your-app.com/telegram/webhook
Usage
The package provides a Telegram
facade for easy interaction with the Telegram Bot API. Below are examples for each supported method, based on tested functionality.
Sending a Message
Send a formatted HTML message with an inline keyboard:
use HugPHP\Telegram\Facades\Telegram; $chatId = config('telegram.default_chat_id', '68*****41'); $message = '<b>Hello</b> from <i>HugPHP</i> <a href="https://hugphp.com">Telegram</a>!'; $response = Telegram::sendMessage($chatId, $message, [ 'parse_mode' => 'HTML', 'reply_markup' => json_encode([ 'inline_keyboard' => [ [['text' => 'Visit Website', 'url' => 'https://github.com/hugphp/telegram']], [['text' => 'Open MinApp', 'web_app' => ['url' => 'https://github.com/hugphp/telegram']]], ], ]), ]);
Example Response:
{ "ok": true, "result": { "message_id": 34, "from": { "id": 78*****897, "is_bot": true, "first_name": "hugphp telegram", "username": "HugPHPTelegramBot" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745171806, "text": "Hello from HugPHP Telegram!", "entities": [ {"offset": 0, "length": 5, "type": "bold"}, {"offset": 11, "length": 6, "type": "italic"}, {"offset": 18, "length": 8, "type": "text_link", "url": "https://hugphp.com/"} ], "reply_markup": { "inline_keyboard": [ [{"text": "Visit Website", "url": "https://github.com/hugphp/telegram"}], [{"text": "Open MinApp", "web_app": {"url": "https://github.com/hugphp/telegram"}}] ] } } }
Sending a Photo
Send a photo with a caption:
$response = Telegram::sendPhoto($chatId, 'https://tailwindcss.com/plus-assets/img/component-images/dark-project-app-screenshot.png', [ 'caption' => 'Test photo', ]);
Example Response:
{ "ok": true, "result": { "message_id": 35, "from": { "id": 78*****897, "is_bot": true, "first_name": "hugphp telegram", "username": "HugPHPTelegramBot" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745171806, "photo": [ { "file_id": "AgACAgQAAxkDAAMPaAPvxocvYpM5Bxm1xZJVv-R3-XYAApq3MRux3V1S-1eP43y186gBAAMCAANzAAM2BA", "file_unique_id": "AQADmrcxG7HdXVJ4", "file_size": 843, "width": 90, "height": 53 }, ... ], "caption": "Test photo" } }
Sending a Video
Send a video with a caption:
$response = Telegram::sendVideo($chatId, 'https://cdn.pixabay.com/video/2025/03/28/268290_large.mp4', [ 'caption' => 'Test video', ]);
Example Response:
{ "ok": true, "result": { "message_id": 36, "from": { "id": 78*****897, "is_bot": true, "first_name": "hugphp telegram", "username": "HugPHPTelegramBot" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745171807, "video": { "duration": 21, "width": 1920, "height": 1080, "file_name": "268290_large.mp4", "mime_type": "video/mp4", "file_id": "BAACAgQAAxkDAAMUaAUz0xMkTfAt6U5fpThEhdoNLWYAAqYHAAKpO_xTHX5XZpe5yrI2BA", "file_unique_id": "AgADpgcAAqk7_FM", "file_size": 12950075 }, "caption": "Test video" } }
Sending a Document
Send a document with a caption:
$response = Telegram::sendDocument($chatId, 'https://www.fsa.usda.gov/Internet/FSA_File/tech_assist.pdf', [ 'caption' => 'Test document', ]);
Example Response:
{ "ok": true, "result": { "message_id": 37, "from": { "id": 78*****897, "is_bot": true, "first_name": "hugphp telegram", "username": "HugPHPTelegramBot" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745171808, "document": { "file_name": "tech_assist.pdf", "mime_type": "application/pdf", "file_id": "BQACAgQAAxkDAAMQaAPwZ9Q1XR_bK67ZeHQTnSdtDDMAAuEHAAIU78RTo-YwBHZMf-s2BA", "file_unique_id": "AgAD4QcAAhTvxFM", "file_size": 60232 }, "caption": "Test document" } }
Sending a Location
Send a live location:
$response = Telegram::sendLocation($chatId, 51.5074, -0.1278, [ 'live_period' => 3600, ]);
Example Response:
{ "ok": true, "result": { "message_id": 38, "from": { "id": 78*****897, "is_bot": true, "first_name": "hugphp telegram", "username": "HugPHPTelegramBot" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745171808, "location": { "latitude": 51.507394, "longitude": -0.127813, "live_period": 3600 } } }
Sending a Contact
Send a contact with first and last name:
$response = Telegram::sendContact($chatId, '+1234567890', 'John Doe', [ 'last_name' => 'Smith', ]);
Example Response:
{ "ok": true, "result": { "message_id": 39, "from": { "id": 78*****897, "is_bot": true, "first_name": "hugphp telegram", "username": "HugPHPTelegramBot" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745171809, "contact": { "phone_number": "+1234567890", "first_name": "John Doe", "last_name": "Smith" } } }
Setting a Webhook
Set a webhook for receiving updates:
$webhookUrl = config('telegram.webhook_url', ''); $response = Telegram::setWebhook($webhookUrl, [ 'max_connections' => config('telegram.webhook_max_connections', 40), 'allowed_updates' => config('telegram.webhook_allowed_updates', []), ]);
Example Response:
{ "ok": true, "result": true, "description": "Webhook was set" }
Getting Webhook Info
Retrieve webhook information:
$response = Telegram::getWebhookInfo();
Example Response:
{ "ok": true, "result": { "url": "https://your-app.com/telegram/webhook", "has_custom_certificate": false, "pending_update_count": 4, "max_connections": 40, "ip_address": "3.18.7.81" } }
Deleting a Webhook
Delete the current webhook:
$response = Telegram::deleteWebhook();
Example Response:
{ "ok": true, "result": true, "description": "Webhook was deleted" }
Getting Updates
Retrieve bot updates:
$response = Telegram::getUpdates([ 'limit' => 10, ]);
Example Response:
{ "ok": true, "result": [ { "update_id": 261265780, "message": { "message_id": 18, "from": { "id": 68*****41, "is_bot": false, "first_name": "Mike", "username": "micheal_ataklt", "language_code": "en" }, "chat": { "id": 68*****41, "first_name": "Mike", "username": "micheal_ataklt", "type": "private" }, "date": 1745143447, "location": { "latitude": 8.891756, "longitude": 38.834948, "live_period": 2147483647 } } }, ... ] }
Testing
The package includes a comprehensive test suite with 100% coverage using Pest. You can test all functionalities in your Laravel project by accessing the /validate-all-functionalities
route:
<?php use HugPHP\Telegram\Facades\Telegram; use Illuminate\Support\Facades\Route; // ----- Route::get('/validate-all-functionalities', function (): array { $chatId = config('telegram.default_chat_id', '68*****41'); $webhookUrl = config('telegram.webhook_url', ''); $results = []; // Test sendMessage try { $messageInHtml = '<b>Hello</b> from <i>HugPHP</i> <a href="https://hugphp.com">Telegram</a>!'; $results['sendMessage'] = [ 'status' => 'success', 'response' => Telegram::sendMessage($chatId, $messageInHtml, [ 'parse_mode' => 'HTML', 'reply_markup' => json_encode([ 'inline_keyboard' => [ [['text' => 'Visit Website', 'url' => 'https://github.com/hugphp/telegram']], [['text' => 'Open MinApp', 'web_app' => ['url' => 'https://github.com/hugphp/telegram']]], ], ]), ]), ]; } catch (\RuntimeException $e) { $results['sendMessage'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test sendPhoto try { $results['sendPhoto'] = [ 'status' => 'success', 'response' => Telegram::sendPhoto($chatId, 'https://tailwindcss.com/plus-assets/img/component-images/dark-project-app-screenshot.png', [ 'caption' => 'Test photo', ]), ]; } catch (\RuntimeException $e) { $results['sendPhoto'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test sendVideo try { $results['sendVideo'] = [ 'status' => 'success', 'response' => Telegram::sendVideo($chatId, 'https://cdn.pixabay.com/video/2025/03/28/268290_large.mp4', [ 'caption' => 'Test video', ]), ]; } catch (\RuntimeException $e) { $results['sendVideo'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test sendDocument try { $results['sendDocument'] = [ 'status' => 'success', 'response' => Telegram::sendDocument($chatId, 'https://www.fsa.usda.gov/Internet/FSA_File/tech_assist.pdf', [ 'caption' => 'Test document', ]), ]; } catch (\RuntimeException $e) { $results['sendDocument'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test sendLocation try { $results['sendLocation'] = [ 'status' => 'success', 'response' => Telegram::sendLocation($chatId, 51.5074, -0.1278, [ 'live_period' => 3600, ]), ]; } catch (\RuntimeException $e) { $results['sendLocation'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test sendContact try { $results['sendContact'] = [ 'status' => 'success', 'response' => Telegram::sendContact($chatId, '+1234567890', 'John Doe', [ 'last_name' => 'Smith', ]), ]; } catch (\RuntimeException $e) { $results['sendContact'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test setWebhook try { $results['setWebhook'] = [ 'status' => 'success', 'response' => Telegram::setWebhook($webhookUrl, [ 'max_connections' => config('telegram.webhook_max_connections', 40), 'allowed_updates' => config('telegram.webhook_allowed_updates', []), ]), ]; } catch (\RuntimeException $e) { $results['setWebhook'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test getWebhookInfo try { $results['getWebhookInfo'] = [ 'status' => 'success', 'response' => Telegram::getWebhookInfo(), ]; } catch (\RuntimeException $e) { $results['getWebhookInfo'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test deleteWebhook try { $results['deleteWebhook'] = [ 'status' => 'success', 'response' => Telegram::deleteWebhook(), ]; } catch (\RuntimeException $e) { $results['deleteWebhook'] = ['status' => 'error', 'error' => $e->getMessage()]; } // Test getUpdates try { $results['getUpdates'] = [ 'status' => 'success', 'response' => Telegram::getUpdates([ 'limit' => 10, ]), ]; } catch (\RuntimeException $e) { $results['getUpdates'] = ['status' => 'error', 'error' => $e->getMessage()]; } return $results; });
curl http://test-project.test/validate-all-functionalities
This route tests all Telegram API methods and returns a JSON response with the status and results for each:
{ "sendMessage": {"status": "success", "response": {...}}, "sendPhoto": {"status": "success", "response": {...}}, "sendVideo": {"status": "success", "response": {...}}, "sendDocument": {"status": "success", "response": {...}}, "sendLocation": {"status": "success", "response": {...}}, "sendContact": {"status": "success", "response": {...}}, "setWebhook": {"status": "success", "response": {...}}, "getWebhookInfo": {"status": "success", "response": {...}}, "deleteWebhook": {"status": "success", "response": {...}}, "getUpdates": {"status": "success", "response": {...}} }
Run unit tests to verify the package:
composer test:unit
Check test coverage:
./vendor/bin/pest --coverage --min=100
Contributing
Contributions are welcome! Please submit a pull request or open an issue on GitHub.
License
This package is open-source software licensed under the MIT License.
Support
Hugphp Telegram was created by Micheal Ataklt.
For questions or support, open an issue on GitHub or contact the maintainer at matakltm.code@gmail.com.