jmuraca / php-telegram-feedback-widget
Drop-in feedback widget that sends user feedback to Telegram. Works with any PHP framework.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/jmuraca/php-telegram-feedback-widget
Requires
- php: ^8.1
- ext-json: *
- longman/telegram-bot: ^0.83
Requires (Dev)
- phpunit/phpunit: ^10.0 || ^11.0
This package is auto-updated.
Last update: 2025-12-23 09:31:01 UTC
README
A drop-in feedback widget that sends user feedback directly to Telegram. Works with any PHP framework or plain PHP.
Features
- Slide-out feedback panel with smooth animations
- Sends feedback to Telegram in real-time
- Framework-agnostic (works with Laravel, Symfony, plain PHP, etc.)
- Vanilla JavaScript (no build step required)
- Fully customizable (colors, fields, texts)
- Accessibility support (keyboard navigation, reduced motion)
- Mobile responsive
Installation
composer require jmuraca/php-telegram-feedback-widget
Quick Start
1. Set up Telegram Bot
- Message @BotFather on Telegram
- Send
/newbotand follow the prompts - Save the bot token you receive
- Start a chat with your bot and send a message
- Get your chat ID by visiting:
https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
2. Backend Setup
<?php require 'vendor/autoload.php'; use TelegramFeedbackWidget\Config; use TelegramFeedbackWidget\FeedbackWidget; $config = new Config([ 'telegram_bot_token' => getenv('TELEGRAM_BOT_TOKEN'), 'telegram_chat_id' => getenv('TELEGRAM_CHAT_ID'), ]); $widget = new FeedbackWidget($config); // Handle form submission if ($_SERVER['REQUEST_URI'] === '/api/feedback/submit' && $_SERVER['REQUEST_METHOD'] === 'POST') { header('Content-Type: application/json'); $response = $widget->handleSubmission($_POST); http_response_code($response['code'] ?? 200); echo json_encode($response); exit; }
3. Frontend Setup
Copy the assets to your public directory:
TelegramFeedbackWidget\FeedbackWidget::publishAssets('/path/to/public/assets/feedback');
Then include in your HTML:
<!-- Include CSS in <head> --> <link rel="stylesheet" href="/assets/feedback/feedback-widget.css"> <!-- Include Font Awesome for icons (optional but recommended) --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <!-- Include JS before </body> --> <script src="/assets/feedback/feedback-widget.js"></script> <script> new FeedbackWidget({ submitEndpoint: '/api/feedback/submit' }); </script>
Configuration
PHP Configuration Options
$config = new Config([ // Required 'telegram_bot_token' => 'YOUR_BOT_TOKEN', 'telegram_chat_id' => 'YOUR_CHAT_ID', // Optional 'required_fields' => ['user_name', 'user_email', 'message'], // Required fields 'environment_name' => 'production', // Shown in Telegram messages ]);
JavaScript Configuration Options
new FeedbackWidget({ // Endpoints submitEndpoint: '/api/feedback/submit', // Appearance position: 'right', // 'right' or 'left' buttonText: 'FEEDBACK', buttonIcon: 'fas fa-comment-dots', // Font Awesome class or null // Form Fields fields: [ { name: 'user_name', type: 'text', label: 'Name', required: true }, { name: 'user_email', type: 'email', label: 'Email', required: true }, { name: 'reason', type: 'select', label: "What's this about?", required: true, options: [ { value: '', label: 'Select a topic' }, { value: 'sales', label: 'Sales' }, { value: 'support', label: 'Support' }, { value: 'other', label: 'Other' } ] }, { name: 'message', type: 'textarea', label: 'Message', required: true, rows: 6 } ], // Hidden Fields (auto-populated) hiddenFields: ['user_id', 'referrer_url'], // Pre-fill user data getUserData: function() { return window.currentUser ? { name: window.currentUser.name, email: window.currentUser.email, id: window.currentUser.id } : null; }, // Callbacks onOpen: function() { console.log('Widget opened'); }, onClose: function() { console.log('Widget closed'); }, onSubmitSuccess: function(response) { console.log('Success', response); }, onSubmitError: function(error) { console.log('Error', error); }, // Texts texts: { title: 'What are you looking for?', submitButton: 'Submit', submitting: 'Submitting...', successTitle: 'Thank you!', successMessage: "Your feedback has been submitted. We'll get back to you soon!", errorTitle: 'Oops! Something went wrong', closeButton: 'Close', tryAgainButton: 'Try Again' } });
CSS Customization
Override CSS variables to customize colors:
:root { --feedback-primary: #28D792; --feedback-primary-hover: #0B624D; --feedback-submit: #FFED37; --feedback-submit-hover: #F5E000; --feedback-submit-text: #1F1F1F; --feedback-panel-width: 500px; }
Framework Examples
Laravel
// routes/api.php use TelegramFeedbackWidget\Config; use TelegramFeedbackWidget\FeedbackWidget; Route::post('/feedback/submit', function (Request $request) { $config = new Config([ 'telegram_bot_token' => config('services.telegram.bot_token'), 'telegram_chat_id' => config('services.telegram.chat_id'), ]); $widget = new FeedbackWidget($config); return response()->json($widget->handleSubmission($request->all())); });
Symfony
// src/Controller/FeedbackController.php use Symfony\Component\HttpFoundation\JsonResponse; use TelegramFeedbackWidget\Config; use TelegramFeedbackWidget\FeedbackWidget; class FeedbackController extends AbstractController { #[Route('/api/feedback/submit', methods: ['POST'])] public function submit(Request $request): JsonResponse { $config = new Config([ 'telegram_bot_token' => $this->getParameter('telegram.bot_token'), 'telegram_chat_id' => $this->getParameter('telegram.chat_id'), ]); $widget = new FeedbackWidget($config); return $this->json($widget->handleSubmission($request->request->all())); } }
API Reference
FeedbackWidget
// Create widget $widget = new FeedbackWidget(Config $config); // Handle form submission (returns array with success/error) $widget->handleSubmission(array $postData); // Test Telegram connection $widget->testConnection(): bool; // Get asset paths FeedbackWidget::getAssetPath('css'); // Returns absolute path FeedbackWidget::getAssetPath('js'); // Copy assets to public directory FeedbackWidget::publishAssets('/path/to/public/dir');
Response Format
Success:
{
"success": true,
"message": "Feedback submitted successfully"
}
Error:
{
"success": false,
"error": "Error message",
"code": 422
}
License
MIT License - see LICENSE
