### Manually Set Up Git Hooks Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Manually configures the Git hooks for the repository. This command should be used if the automatic setup via `composer install` fails. ```bash composer setup-hooks ``` -------------------------------- ### Install Xmon Notification Bundle with Composer Source: https://github.com/xmon-org/notification-bundle/blob/main/README.md This command installs the Xmon Notification Bundle using Composer. Ensure you have Composer installed and your project is managed by it. ```bash composer require xmon-org/notification-bundle ``` -------------------------------- ### Install Project Dependencies with Composer Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Installs all project dependencies and automatically configures Git hooks using Composer. This command should be run after cloning the repository. ```bash composer install ``` -------------------------------- ### Verify Development Setup with Composer Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Runs all validation checks for the development setup, including CS-Fixer (dry-run), PHPStan static analysis, and tests. This command helps ensure the environment is correctly configured. ```bash composer check ``` -------------------------------- ### Complete Example: Sending Article Notifications Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md A comprehensive example demonstrating how to send an article notification with a photo, caption, and custom buttons using the `TelegramService`. ```APIDOC ## Complete Example: Sending Article Notifications This example shows how to send a new article notification to multiple chat IDs, including a photo, formatted caption, and action buttons. ### Class `NewsNotifier` ```php use Xmon\NotificationBundle\Telegram\TelegramService; use Xmon\NotificationBundle\Telegram\TelegramButton; class NewsNotifier { public function __construct( private readonly TelegramService $telegram, ) {} public function notifyNewArticle(Article $article): void { $buttons = [ TelegramButton::callback('Publish', "publish:{$article->getId()}"), TelegramButton::callback('Discard', "discard:{$article->getId()}"), TelegramButton::url('Edit', $this->getEditUrl($article)), ]; $caption = sprintf( "* %s *\n\n%s", TelegramService::escapeMarkdown($article->getTitle()), TelegramService::escapeMarkdown($article->getSummary()) ); // Send to all configured chat_ids foreach ($this->telegram->getChatIds() as $chatId) { $result = $this->telegram->sendPhoto( chatId: $chatId, photo: $article->getImageUrl(), caption: $caption, buttons: $buttons, buttonLayout: [[0, 1], [2]], // 2 buttons top, 1 bottom ); if ($result['ok']) { // Save message_id to edit/delete later $article->setTelegramMessageId($result['message_id']); } } } } ``` ### Method: `notifyNewArticle` #### Description Sends a notification for a new article to configured chat IDs. #### Parameters - **$article** (Article) - Required - The article object containing details to be sent. #### Request Body *N/A - This method is called internally.* #### Response *The method returns void, but internally interacts with the Telegram API.* #### Success Response Example (from `sendPhoto`) ```json { "ok": true, "result": { "message_id": 12345, "chat": { "id": 123456789, "type": "private" }, "date": 1678886400, "photo": [ // ... photo details ... ], "caption": "*Article Title*\n\nArticle Summary" } } ``` #### Error Response Example (from `sendPhoto`) ```json { "ok": false, "error_code": 400, "description": "Bad Request: chat not found" } ``` ``` -------------------------------- ### Guided Conversation Pattern Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Demonstrates how to implement multi-step conversations using `sendMessageWithForceReply` and `TelegramMessageEvent` to guide user input. ```APIDOC ## Guided Conversation Pattern Combine `sendMessageWithForceReply()` with `TelegramMessageEvent` for multi-step conversations. ### Step 1: Ask for Input Use `sendMessageWithForceReply` in your callback listener to prompt the user for specific input. ```php // Step 1: In callback listener, ask for input $this->telegramService->sendMessageWithForceReply( chatId: $event->getChatId(), text: "Current title:\n\n`{$article->getTitle()}`\n\nSend the new title:", inputFieldPlaceholder: 'Enter new title...', ); // Save state (chatId, articleId, field='title') in database ``` ### Step 2: Process Reply In your message listener, retrieve the saved state and process the user's reply to update the relevant field. ```php // Step 2: In message listener, process the reply $state = $this->findActiveState($event->getChatId(), $event->getUserId()); if ($state && $state->getField() === 'title') { $article = $state->getArticle(); $article->setTitle($event->getText()); // Clear state, send confirmation } ``` ``` -------------------------------- ### Conventional Commit Message Example Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Provides examples of commit messages adhering to the Conventional Commits specification. This format helps in automatically generating changelogs and understanding the nature of changes. ```bash feat(telegram): add inline keyboard support fix(email): handle empty recipient list docs: update installation instructions ``` -------------------------------- ### PHP Example: Sending New Article Notification with Buttons Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md A complete PHP example demonstrating how to send a new article notification via Telegram. It utilizes `sendPhoto` to include an image and `TelegramButton` to attach inline keyboard actions like 'Publish', 'Discard', and a URL button for 'Edit'. It also includes Markdown escaping for text formatting. ```php use Xmon\NotificationBundle\Telegram\TelegramService; use Xmon\NotificationBundle\Telegram\TelegramButton; class NewsNotifier { public function __construct( private readonly TelegramService $telegram, ) {} public function notifyNewArticle(Article $article): void { $buttons = [ TelegramButton::callback('Publish', "publish:{$article->getId()}"), TelegramButton::callback('Discard', "discard:{$article->getId()}"), TelegramButton::url('Edit', $this->getEditUrl($article)), ]; $caption = sprintf( "* %s *\n\n%s", TelegramService::escapeMarkdown($article->getTitle()), TelegramService::escapeMarkdown($article->getSummary()) ); // Send to all configured chat_ids foreach ($this->telegram->getChatIds() as $chatId) { $result = $this->telegram->sendPhoto( chatId: $chatId, photo: $article->getImageUrl(), caption: $caption, buttons: $buttons, buttonLayout: [[0, 1], [2]], // 2 buttons top, 1 bottom ); if ($result['ok']) { // Save message_id to edit/delete later $article->setTelegramMessageId($result['message_id']); } } } } ``` -------------------------------- ### PHP TelegramService Photo Sending Example Source: https://context7.com/xmon-org/notification-bundle/llms.txt Shows how to use the TelegramService to send a photo with a caption and inline keyboard buttons. This method requires a valid TelegramService instance and utilizes TelegramButton for button creation. The input includes chat ID, photo URL/path, caption, and button layout. ```php use Xmon\NotificationBundle\Telegram\TelegramService; use Xmon\NotificationBundle\Telegram\TelegramButton; class NewsNotifier { public function __construct( private TelegramService $telegram, ) {} public function sendArticleForReview(Article $article): void { // Create inline keyboard buttons $buttons = [ TelegramButton::callback('Publish', "publish:{$article->getId()}"), TelegramButton::callback('Reject', "reject:{$article->getId()}"), TelegramButton::url('Edit', "https://example.com/edit/{$article->getId()}"), ]; // Send photo with caption and buttons $result = $this->telegram->sendPhoto( chatId: $this->telegram->getDefaultChatId(), photo: $article->getImageUrl(), // URL or local file path caption: sprintf( "* %s *\n\n%s", TelegramService::escapeMarkdown($article->getTitle()), TelegramService::escapeMarkdown($article->getSummary()) ), buttons: $buttons, buttonLayout: [[0, 1], [2]], // 2 buttons first row, 1 button second row ); if ($result['ok']) { // Store message ID for later editing $article->setTelegramMessageId($result['message_id']); } } public function sendSimpleMessage(string $chatId, string $text): void { $result = $this->telegram->sendMessage( chatId: $chatId, text: "*Important Alert*\n\nServer CPU usage at 95%", buttons: [ TelegramButton::callback('Acknowledge', 'ack:server-cpu'), TelegramButton::url('View Dashboard', 'https://monitoring.example.com'), ], ); } public function sendCelebration(string $chatId): void { // Send animated sticker (requires sticker file_id) $this->telegram->sendSticker( chatId: $chatId, sticker: 'CAACAgIAAxkBAAOm...', // Telegram sticker file_id ); } } ``` -------------------------------- ### Configure Telegram Webhook Route in YAML Source: https://context7.com/xmon-org/notification-bundle/llms.txt This YAML configuration defines the route for the Telegram webhook controller. It specifies the path for incoming webhooks and maps it to the `TelegramWebhookController`. This setup is essential for receiving updates from the Telegram Bot API. The controller handles POST requests to the specified path. ```yaml # config/routes/xmon_notification.yaml xmon_notification_telegram_webhook: path: /webhook/telegram controller: Xmon\NotificationBundle\Controller\TelegramWebhookController methods: [POST] ``` -------------------------------- ### PHP Guided Conversation Pattern with Telegram Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Demonstrates a multi-step conversation flow using `sendMessageWithForceReply` and `TelegramMessageEvent`. It involves saving conversation state to a database to manage user input across multiple messages. This pattern is useful for collecting sequential information from users. ```php use Xmon\NotificationBundle\Telegram\TelegramMessageEvent; use Xmon\NotificationBundle\Telegram\TelegramService; // Step 1: In callback listener, ask for input $this->telegramService->sendMessageWithForceReply( chatId: $event->getChatId(), text: "Current title:\n\n`{$article->getTitle()}`\n\nSend the new title:", inputFieldPlaceholder: 'Enter new title...' ); // Save state (chatId, articleId, field='title') in database // Step 2: In message listener, process the reply $state = $this->findActiveState($event->getChatId(), $event->getUserId()); if ($state && $state->getField() === 'title') { $article = $state->getArticle(); $article->setTitle($event->getText()); // Clear state, send confirmation } ``` -------------------------------- ### Send Notification with NotificationService (PHP) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/email.md Example of sending a simple email notification using the NotificationService. It constructs a SimpleNotification object and a Recipient, then sends it via the service. It also shows how to handle the results. ```php use Xmon\NotificationBundle\Notification\SimpleNotification; use Xmon\NotificationBundle\Recipient\Recipient; use Xmon\NotificationBundle\Service\NotificationService; class WelcomeService { public function __construct( private readonly NotificationService $notificationService, ) {} public function sendWelcome(User $user): void { $notification = new SimpleNotification( title: 'Welcome to our platform', content: "Hello {$user->getName()},\n\nThank you for signing up.", channels: ['email'], ); $recipient = new Recipient( email: $user->getEmail(), ); $results = $this->notificationService->send($notification, $recipient); foreach ($results as $result) { if ($result->isSuccess()) { // Email sent } else { // Error: $result->getMessage() } } } } ``` -------------------------------- ### Subscribe to Notification Events (PHP) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/email.md Example of creating an event subscriber to hook into the notification lifecycle. It implements EventSubscriberInterface and defines handlers for pre-send, sent, and failed events. ```php use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Xmon\NotificationBundle\Event\NotificationPreSendEvent; use Xmon\NotificationBundle\Event\NotificationSentEvent; use Xmon\NotificationBundle\Event\NotificationFailedEvent; class NotificationSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ NotificationPreSendEvent::class => 'onPreSend', NotificationSentEvent::class => 'onSent', NotificationFailedEvent::class => 'onFailed', ]; } public function onPreSend(NotificationPreSendEvent $event): void { // Modify notification before sending // Or cancel the send: // $event->cancel(); } public function onSent(NotificationSentEvent $event): void { // Log success } public function onFailed(NotificationFailedEvent $event): void { // Log error, retry, etc. } } ``` -------------------------------- ### TelegramButton: Define Button Layout and Send Message Source: https://context7.com/xmon-org/notification-bundle/llms.txt Illustrates how to arrange multiple Telegram buttons into different layouts for inline keyboards. The `buttonLayout` parameter in `sendMessage` controls how buttons are displayed in rows. This example shows how to create various row configurations, from all buttons in one row to each button on its own row. ```php use Xmon\NotificationBundle\Telegram\TelegramButton; // Button layout examples $buttons = [ TelegramButton::callback('Accept', 'accept:123'), // index 0 TelegramButton::callback('Reject', 'reject:123'), // index 1 TelegramButton::url('Details', 'https://...'), // index 2 TelegramButton::callback('Skip', 'skip:123'), // index 3 ]; // All buttons in one row: [Accept] [Reject] [Details] [Skip] $layout1 = [[0, 1, 2, 3]]; // Two rows: [Accept] [Reject] / [Details] [Skip] $layout2 = [[0, 1], [2, 3]]; // Three rows: [Accept] [Reject] / [Details] / [Skip] $layout3 = [[0, 1], [2], [3]]; // Four rows (one button each): [Accept] / [Reject] / [Details] / [Skip] $layout4 = [[0], [1], [2], [3]]; $this->telegram->sendMessage( chatId: $chatId, text: 'Choose an action:', buttons: $buttons, buttonLayout: $layout2, ); ``` -------------------------------- ### Obtaining Telegram Sticker file_id Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Provides instructions and an example of how to obtain the unique `file_id` for a sticker by temporarily disabling webhooks, sending a sticker, querying updates, and then re-enabling the webhook. This is necessary for referencing stickers in subsequent API calls. ```bash # 1. Temporarily disable webhook: https://api.telegram.org/bot{TOKEN}/deleteWebhook # 3. Query updates: https://api.telegram.org/bot{TOKEN}/getUpdates # 4. Re-enable webhook: https://api.telegram.org/bot{TOKEN}/setWebhook?url=https://your-domain.com/webhook/telegram ``` ```json { "message": { "sticker": { "file_id": "CAACAgIAAxkBAAI...", "is_animated": true } } } ``` -------------------------------- ### Getting Sticker file_id Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Instructions on how to obtain a sticker's `file_id`, which is unique per bot, by temporarily disabling webhooks and querying updates. ```APIDOC ## Getting Sticker file_id Sticker `file_id`s are unique per bot. To obtain them, follow these steps: ### 1. Temporarily Disable Webhook ``` https://api.telegram.org/bot{TOKEN}/deleteWebhook ``` ### 2. Send a Sticker to the Bot Initiate a chat with your bot on Telegram and send a sticker. ### 3. Query Updates Use the `getUpdates` method to retrieve the sent message details, including the sticker's `file_id`. ``` https://api.telegram.org/bot{TOKEN}/getUpdates ``` **Response Example (within JSON updates):** ```json { "message": { "sticker": { "file_id": "CAACAgIAAxkBAAI...", "is_animated": true } } } ``` ### 4. Re-enable Webhook Once you have the `file_id`, re-enable your webhook. ``` https://api.telegram.org/bot{TOKEN}/setWebhook?url=https://your-domain.com/webhook/telegram ``` ``` -------------------------------- ### Handle Telegram Text Messages (PHP) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Provides an example of listening to `TelegramMessageEvent` to process text messages sent by users. This is useful for implementing conversational flows or receiving user input. The listener can access message text, chat ID, user ID, and determine if the message is a reply to a previous message. ```php use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Xmon\NotificationBundle\Event\TelegramMessageEvent; #[AsEventListener(event: TelegramMessageEvent::class)] final class MyMessageListener { public function __invoke(TelegramMessageEvent $event): void { $text = $event->getText(); $chatId = $event->getChatId(); $userId = $event->getUserId(); // Check if this is a reply to a specific message $replyToId = $event->getReplyToMessageId(); if ($replyToId === null) { return; // Not a reply, maybe not relevant } // Process the reply... // e.g., update content in database based on conversation state $event->setHandled(true); $event->setResponseMessage('Content updated!'); // Optional response } } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Executes all unit tests for the notification bundle using PHPUnit. This command verifies the correctness of the implemented features and fixes. ```bash composer test ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Runs unit tests and generates a code coverage report. This helps in assessing the thoroughness of the test suite. ```bash composer test:coverage ``` -------------------------------- ### Send Notification with Priority (PHP) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/email.md Example of setting a priority for an email notification. The NotificationPriority enum provides options like Low, Normal, High, and Urgent. ```php use Xmon\NotificationBundle\Notification\NotificationPriority; $notification = new SimpleNotification( title: 'Security Alert', content: 'A suspicious login attempt has been detected.', priority: NotificationPriority::Urgent, channels: ['email'], ); ``` -------------------------------- ### Create SimpleNotification Objects (PHP) Source: https://context7.com/xmon-org/notification-bundle/llms.txt The `SimpleNotification` constructor allows for the creation of notification objects. It supports basic content, advanced templating with context, setting notification priority, adding custom metadata, and specifying asynchronous sending. You can configure notifications for single or multiple channels, and tailor them with specific templates and data relevant to the message. ```php use Xmon\NotificationBundle\Notification\SimpleNotification; use Xmon\NotificationBundle\Notification\NotificationPriority; // Basic notification with content only $notification = new SimpleNotification( title: 'Welcome to Our Platform', content: 'Thank you for registering. Start exploring our features!', channels: ['email'], ); // Advanced notification with custom template and context $notification = new SimpleNotification( title: 'Password Reset Request', content: 'You requested a password reset. Click the link below to continue.', template: 'emails/password_reset', context: [ 'reset_token' => $resetToken, 'expiry_time' => new \DateTimeImmutable('+1 hour'), 'user_name' => $user->getName(), ], channels: ['email'], priority: NotificationPriority::Urgent, metadata: ['user_id' => $user->getId()], async: false, ); // Multi-channel notification with different priority $notification = new SimpleNotification( title: 'System Alert: High CPU Usage', content: 'Server CPU usage exceeded 90% threshold', channels: ['email', 'telegram', 'in_app'], priority: NotificationPriority::Urgent, metadata: [ 'server' => 'web-01', 'cpu_usage' => 94.5, 'timestamp' => time(), ], ); ``` -------------------------------- ### TelegramService: Send Message with Force Reply Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Sends a message that prompts the user to reply, useful for guided input. Supports setting a placeholder and controlling reply selectivity. ```php $result = $this->telegramService->sendMessageWithForceReply( chatId: '-1001234567890', text: 'What is the new title?', selective: false, // Only force reply from specific users inputFieldPlaceholder: 'Enter title...', // Placeholder text (max 64 chars) ); if ($result['ok']) { $messageId = $result['message_id']; // Store state to process the reply later } ``` -------------------------------- ### Send Basic Notification in PHP Source: https://github.com/xmon-org/notification-bundle/blob/main/README.md This PHP code demonstrates how to send a basic notification using the NotificationService. It shows how to create a SimpleNotification, define recipients, and send the notification across multiple channels. ```php use Xmon\NotificationBundle\Notification\SimpleNotification; use Xmon\NotificationBundle\Recipient\Recipient; use Xmon\NotificationBundle\Service\NotificationService; class MyService { public function __construct( private NotificationService $notificationService, ) {} public function sendWelcomeEmail(User $user): void { $notification = new SimpleNotification( title: 'Welcome!', content: 'Thanks for joining our platform.', channels: ['email', 'telegram'], ); $recipient = new Recipient( email: $user->getEmail(), telegramChatId: $user->getTelegramChatId(), ); $results = $this->notificationService->send($notification, $recipient); foreach ($results as $result) { if ($result->isSuccess()) { // Handle success } } } } ``` -------------------------------- ### Subscribe to Notification Events in PHP Source: https://github.com/xmon-org/notification-bundle/blob/main/README.md This PHP code demonstrates how to subscribe to notification events, specifically the NotificationPreSendEvent. It shows how to implement the EventSubscriberInterface and define logic to potentially cancel a notification before it's sent. ```php use Xmon\NotificationBundle\Event\NotificationPreSendEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class NotificationSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ NotificationPreSendEvent::class => 'onPreSend', ]; } public function onPreSend(NotificationPreSendEvent $event): void { // Modify notification or cancel sending if ($this->shouldCancel($event->notification)) { $event->cancel(); } } } ``` -------------------------------- ### Clone Notification Bundle Repository Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Clones the Xmon Notification Bundle repository from GitHub and navigates into the project directory. This is the first step in setting up the development environment. ```bash git clone https://github.com/xmon-org/notification-bundle.git cd notification-bundle ``` -------------------------------- ### Configure Notification Bundle Channels and Messenger (YAML) Source: https://context7.com/xmon-org/notification-bundle/llms.txt Provides YAML configuration for the Xmon Notification Bundle, allowing developers to enable and configure various notification channels (email, telegram, in-app), set up asynchronous processing via Messenger, and define default settings for channels and notification priority. ```yaml # config/packages/xmon_notification.yaml xmon_notification: # Channel configuration channels: email: enabled: true from: 'noreply@example.com' from_name: 'My Application' telegram: enabled: true bot_token: '%env(TELEGRAM_BOT_TOKEN)%' default_chat_id: '%env(TELEGRAM_DEFAULT_CHAT)%' in_app: enabled: true storage: 'doctrine' # or 'session' max_notifications: 100 # Async processing with Messenger messenger: enabled: true transport: 'async' # Default settings defaults: channels: ['email'] priority: 'normal' ``` -------------------------------- ### Render Notification Content with Twig Templates (PHP) Source: https://context7.com/xmon-org/notification-bundle/llms.txt Demonstrates how to use the TemplateRenderer service to render notification content using Twig templates with custom context. It shows rendering as both HTML and plain text. Dependencies include Xmon\NotificationBundle\Service\TemplateRenderer and Xmon\NotificationBundle\Notification\SimpleNotification. ```php use Xmon\NotificationBundle\Service\TemplateRenderer; use Xmon\NotificationBundle\Notification\SimpleNotification; class CustomNotificationService { public function __construct( private TemplateRenderer $renderer, ) {} public function renderCustomNotification(Order $order): string { $notification = new SimpleNotification( title: 'Order Invoice', content: 'Please find your invoice attached.', template: 'notifications/order_invoice', context: [ 'order' => $order, 'invoice_number' => $order->getInvoiceNumber(), 'items' => $order->getItems(), 'subtotal' => $order->getSubtotal(), 'tax' => $order->getTax(), 'total' => $order->getTotal(), 'customer' => $order->getCustomer(), ], ); // Render as HTML $htmlContent = $this->renderer->render($notification, 'html'); // Or render as plain text $textContent = $this->renderer->render($notification, 'txt'); return $htmlContent; } } ``` -------------------------------- ### Manage and Retrieve Notification Channels with ChannelRegistry (PHP) Source: https://context7.com/xmon-org/notification-bundle/llms.txt Illustrates how to use the ChannelRegistry to check the availability and configuration status of various notification channels. It iterates through a predefined list of channel names and retrieves all registered channels. Dependencies include Xmon\NotificationBundle\Channel\ChannelRegistry and Xmon\NotificationBundle\Exception\ChannelNotConfiguredException. ```php use Xmon\NotificationBundle\Channel\ChannelRegistry; use Xmon\NotificationBundle\Exception\ChannelNotConfiguredException; class NotificationHealthCheck { public function __construct( private ChannelRegistry $channelRegistry, ) {} public function checkChannelAvailability(): array { $status = []; // Check if specific channels are available $channelNames = ['email', 'telegram', 'in_app', 'discord', 'slack']; foreach ($channelNames as $channelName) { $status[$channelName] = [ 'available' => $this->channelRegistry->hasChannel($channelName), 'configured' => false, ]; if ($status[$channelName]['available']) { try { $channel = $this->channelRegistry->getChannel($channelName); $status[$channelName]['configured'] = $channel->isConfigured(); } catch (ChannelNotConfiguredException $e) { $status[$channelName]['error'] = $e->getMessage(); } } } // Get all registered channels $allChannels = $this->channelRegistry->getAllChannels(); $status['total_channels'] = count($allChannels); return $status; } } ``` -------------------------------- ### Run Static Analysis with PHPStan Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Executes PHPStan static analysis at level 5 to perform strict type checking on the codebase. This helps in identifying potential bugs and type-related issues. ```bash composer phpstan ``` -------------------------------- ### Set Telegram Webhook URL and Secret in PHP Source: https://context7.com/xmon-org/notification-bundle/llms.txt This code snippet shows how to configure the Telegram webhook in the Telegram API and optionally set a webhook secret in the services configuration. Setting the webhook URL is a one-time setup to direct Telegram updates to your application. A webhook secret enhances security by verifying the origin of incoming requests. The `TELEGRAM_WEBHOOK_SECRET` environment variable is used for this purpose. ```plaintext # Configure webhook in Telegram (one-time setup): # https://api.telegram.org/bot{YOUR_BOT_TOKEN}/setWebhook?url=https://your-domain.com/webhook/telegram # Optional: Set webhook secret for security # config/services.yaml services: Xmon\NotificationBundle\Controller\TelegramWebhookController: arguments: $webhookSecret: '%env(TELEGRAM_WEBHOOK_SECRET)%' ``` -------------------------------- ### TelegramButton: Create Callback and URL Buttons Source: https://context7.com/xmon-org/notification-bundle/llms.txt Demonstrates the creation of different types of inline keyboard buttons for Telegram messages. `TelegramButton::callback` is used for buttons that trigger events within the bot, while `TelegramButton::url` creates buttons that open web links. Button data for callbacks has a maximum length of 64 bytes. ```php use Xmon\NotificationBundle\Telegram\TelegramButton; // Callback button - triggers TelegramCallbackEvent when clicked $callbackButton = TelegramButton::callback( text: 'Approve Request', data: 'approve:request:42', // Max 64 bytes, will be in event->getCallbackData() ); // URL button - opens link in browser $urlButton = TelegramButton::url( text: 'View Documentation', url: 'https://docs.example.com/guide', ); ``` -------------------------------- ### SimpleNotification Constructor Source: https://context7.com/xmon-org/notification-bundle/llms.txt Creates a notification object with configurable channels, priority, template, and context. This object is used as part of the request payload for sending notifications. ```APIDOC ## POST /notifications/create ### Description This endpoint (conceptually represented by the `SimpleNotification` constructor) allows for the creation of a `SimpleNotification` object. This object encapsulates all the details required to send a notification, including its content, target channels, priority, and any associated data for templating or logging. ### Method `POST` ### Endpoint `/notifications/create` ### Parameters #### Request Body - **title** (string) - Required - The title of the notification. - **content** (string) - Required - The main body content of the notification. - **channels** (array) - Required - An array of channel names (e.g., 'email', 'telegram', 'in_app') to send the notification through. - **priority** (string) - Optional - The priority level of the notification (e.g., 'High', 'Urgent', 'Normal'). Defaults to 'Normal'. - **template** (string) - Optional - The name of the template to use for rendering the notification content. - **context** (object) - Optional - An object containing data to be used in the notification template. - **metadata** (object) - Optional - An object containing additional metadata related to the notification. - **async** (boolean) - Optional - Specifies whether the notification should be sent asynchronously. Defaults to `false`. ### Request Example ```json { "title": "Password Reset Request", "content": "You requested a password reset. Click the link below to continue.", "template": "emails/password_reset", "context": { "reset_token": "abcdef12345", "expiry_time": "2023-10-27T10:00:00+00:00", "user_name": "Jane Doe" }, "channels": ["email"], "priority": "Urgent", "metadata": { "user_id": "user789" }, "async": false } ``` ### Response #### Success Response (200) - **notification** (object) - The created notification object. This is typically used internally by the service and not directly returned to the client in a real API scenario, but represents the structure built. - **title** (string) - The title of the notification. - **content** (string) - The content of the notification. - **channels** (array) - The target channels. - **priority** (string) - The notification priority. - **template** (string) - The template used. - **context** (object) - The context data. - **metadata** (object) - Additional metadata. - **async** (boolean) - Asynchronous flag. #### Response Example ```json { "notification": { "title": "Password Reset Request", "content": "You requested a password reset. Click the link below to continue.", "channels": ["email"], "priority": "Urgent", "template": "emails/password_reset", "context": { "reset_token": "abcdef12345", "expiry_time": "2023-10-27T10:00:00+00:00", "user_name": "Jane Doe" }, "metadata": { "user_id": "user789" }, "async": false } } ``` ``` -------------------------------- ### Configure Xmon Notification Bundle Channels Source: https://github.com/xmon-org/notification-bundle/blob/main/README.md This YAML configuration snippet shows how to enable and configure different notification channels (Email, Telegram, In-App) and Messenger integration. It includes settings for sender information, API tokens, chat IDs, and storage options. ```yaml xmon_notification: channels: email: enabled: true from: 'noreply@example.com' from_name: 'My App' telegram: enabled: true bot_token: '%env(TELEGRAM_BOT_TOKEN)%' chat_ids: - '%env(TELEGRAM_CHAT_ID)%' webhook_secret: '%env(default::TELEGRAM_WEBHOOK_SECRET)%' in_app: enabled: true storage: 'session' # session | doctrine max_notifications: 50 messenger: enabled: false transport: 'async' defaults: channels: ['email'] priority: 'normal' ``` -------------------------------- ### Configure Email Channel (YAML) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/email.md YAML configuration for enabling the email channel, setting the 'from' address, and optionally the 'from_name'. Requires Symfony Mailer to be configured. ```yaml # config/packages/xmon_notification.yaml xmon_notification: channels: email: enabled: true from: 'noreply@example.com' from_name: 'My Application' # optional ``` -------------------------------- ### Telegram Button Types Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Demonstrates how to create different types of Telegram buttons: callback buttons for triggering events and URL buttons for opening links. ```APIDOC ## Button Types ### Callback Button Creates a button that triggers an event when clicked. The `data` can be up to 64 bytes. ```php use Xmon\NotificationBundle\Telegram\TelegramButton; $button = TelegramButton::callback( text: 'Publish', data: 'publish:123' ); ``` ### URL Button Creates a button that opens a specified URL when clicked. ```php use Xmon\NotificationBundle\Telegram\TelegramButton; $button = TelegramButton::url( text: 'View article', url: 'https://example.com/article/123' ); ``` ``` -------------------------------- ### Handling Telegram Callbacks Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Provides instructions on how to listen for and process `TelegramCallbackEvent`s, which are triggered when users click on inline buttons. ```APIDOC ## Handling Callbacks ### Description Listen to the `TelegramCallbackEvent` to process user interactions with inline buttons. This event is dispatched when a user clicks a button that was sent with `TelegramButton::callback()`. ### Event Listener Example ```php use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Xmon\NotificationBundle\Event\TelegramCallbackEvent; #[AsEventListener(event: TelegramCallbackEvent::class)] final class MyCallbackListener { public function __invoke(TelegramCallbackEvent $event): void { // Parse callback_data (format "action:id" or "action:id:extra") $parsed = $event->parseCallbackData(); $action = $parsed['action']; // e.g.: "publish" $id = $parsed['id']; // e.g.: 123 $extra = $parsed['extra']; // e.g.: "titulo" (optional third segment) if ($action !== 'my_action') { return; // Not for this listener } // Process action... // Respond to user (optional) $event->setHandled(true); $event->setResponseText('Action completed'); // $event->setShowAlert(true); // For popup instead of toast } } ``` ### Event Properties | Method | Description | |--------------------|-------------------------------------------------------------| | `getCallbackQueryId()` | ID for `answerCallbackQuery` | | `getCallbackData()` | Button data (e.g.: "publish:123" or "edit:123:titulo") | | `parseCallbackData()` | Parses to `['action' => ..., 'id' => ..., 'extra' => ...]` | | `getChatId()` | Chat ID | | `getMessageId()` | Message ID containing the button | | `getFrom()` | Info about user who clicked | | `getRawUpdate()` | Complete Telegram payload | ``` -------------------------------- ### TelegramService Injection Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Demonstrates how to inject the TelegramService into a PHP class constructor using type hinting for dependency injection. ```php use Xmon\NotificationBundle\Telegram\TelegramService; public function __construct( private readonly TelegramService $telegramService, ) {} ``` -------------------------------- ### Generate PHPStan Baseline Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Generates a baseline file for PHPStan, which can be used to ignore existing legacy errors. This is useful when introducing static analysis to a project with a large codebase. ```bash composer phpstan:baseline ``` -------------------------------- ### Handle Telegram Callback Events in PHP Source: https://context7.com/xmon-org/notification-bundle/llms.txt This listener demonstrates how to process user interactions with Telegram inline keyboard buttons. It parses callback data, performs business logic (e.g., updating article status), and provides feedback to the user via Telegram messages or alerts. It requires the `XmonNotificationBundleEventTelegramCallbackEvent` and `XmonNotificationBundleTelegramTelegramService`. ```php use Xmon\NotificationBundle\Event\TelegramCallbackEvent; use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Xmon\NotificationBundle\Telegram\TelegramService; #[AsEventListener(event: TelegramCallbackEvent::class)] class ArticlePublishListener { public function __construct( private ArticleRepository $articles, private TelegramService $telegram, ) {} public function __invoke(TelegramCallbackEvent $event): void { // Parse callback data (format: "action:id") $parsed = $event->parseCallbackData(); $action = $parsed['action']; // e.g., "publish" $id = $parsed['id']; // e.g., 123 // Only handle publish actions if ($action !== 'publish') { return; } // Get article and process $article = $this->articles->find($id); if (!$article) { $event->setHandled(true); $event->setResponseText('Article not found'); $event->setShowAlert(true); // Show as popup alert return; } // Perform business logic $article->setStatus('published'); $this->articles->save($article); // Update message to show published state $this->telegram->editMessageCaption( chatId: $event->getChatId(), messageId: $event->getMessageId(), caption: sprintf("✓ *Published*\n\n%s", $article->getTitle()), buttons: [ TelegramButton::url('View Article', $article->getPublicUrl()), ], ); // Respond to user (shows toast notification) $event->setHandled(true); $event->setResponseText(sprintf('Article #%d published successfully', $id)); } } ``` -------------------------------- ### Create Telegram Buttons (PHP) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Demonstrates how to create callback and URL buttons for Telegram messages using the TelegramButton class. Callback buttons trigger events within your application, while URL buttons open external links. The 'data' for callback buttons has a maximum length of 64 bytes. ```php use Xmon\NotificationBundle\Telegram\TelegramButton; // Callback button (triggers event) $button = TelegramButton::callback( text: 'Publish', data: 'publish:123', // max 64 bytes ); // URL button (opens link) $button = TelegramButton::url( text: 'View article', url: 'https://example.com/article/123', ); ``` -------------------------------- ### Define Telegram Button Layout (PHP) Source: https://github.com/xmon-org/notification-bundle/blob/main/docs/telegram.md Illustrates how to define the layout of Telegram buttons using an array of row configurations. Each row is an array of button indices, allowing flexible arrangement of buttons across multiple rows. ```php $buttons = [ TelegramButton::callback('A', 'a'), // index 0 TelegramButton::callback('B', 'b'), // index 1 TelegramButton::callback('C', 'c'), // index 2 TelegramButton::callback('D', 'd'), // index 3 ]; // All in one row: [A] [B] [C] [D] $layout = [[0, 1, 2, 3]]; // Two rows: [A] [B] / [C] [D] $layout = [[0, 1], [2, 3]]; // Three rows: [A] [B] / [C] / [D] $layout = [[0, 1], [2], [3]]; ``` -------------------------------- ### Handle Telegram Callback Events with EventSubscriber in PHP Source: https://context7.com/xmon-org/notification-bundle/llms.txt This PHP class implements `EventSubscriberInterface` to listen for `TelegramCallbackEvent`. It provides a way to centrally handle various callback actions from Telegram. The `getSubscribedEvents` method registers the `onCallback` method to be called when a `TelegramCallbackEvent` is dispatched. Inside `onCallback`, you can access detailed information about the callback and parse its data to perform specific actions, such as processing an order. ```php use Xmon\NotificationBundle\Event\TelegramCallbackEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class OrderCallbackHandler implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ TelegramCallbackEvent::class => 'onCallback', ]; } public function onCallback(TelegramCallbackEvent $event): void { // Access callback information $data = $event->getCallbackData(); // e.g., "confirm_order:456" $chatId = $event->getChatId(); $messageId = $event->getMessageId(); $user = $event->getFrom(); // ['id' => 123, 'first_name' => 'John', ...] $rawUpdate = $event->getRawUpdate(); // Full Telegram update payload // Parse structured callback data $parsed = $event->parseCallbackData(); // Returns: ['action' => 'confirm_order', 'id' => 456] if ($parsed['action'] === 'confirm_order') { $this->processOrder($parsed['id']); $event->setHandled(true); $event->setResponseText('Order confirmed!'); // Set setShowAlert(true) for modal popup instead of toast } } } ``` -------------------------------- ### Send Notification with Custom Template in PHP Source: https://github.com/xmon-org/notification-bundle/blob/main/README.md This PHP code illustrates sending a notification using a custom Twig template. It includes the notification details, template name, and context data for rendering. ```php $notification = new SimpleNotification( title: 'Order Confirmed', content: 'Your order #123 has been confirmed.', template: 'emails/order_confirmation', context: ['order' => $order], channels: ['email'], ); ``` -------------------------------- ### Telegram Callback Event Handling Source: https://context7.com/xmon-org/notification-bundle/llms.txt Details on how to handle Telegram callback events dispatched by the `TelegramCallbackEvent` class. This event is triggered when users interact with inline keyboard buttons in Telegram, enabling interactive workflows. ```APIDOC ## TelegramCallbackEvent ### Description Event dispatched when users click inline keyboard buttons, enabling interactive workflows. ### Method Not Applicable (Event-driven) ### Endpoint Not Applicable (Event-driven) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example This section is not applicable as this is an event, not an API endpoint to be called directly. ### Response #### Success Response (Event Handled) - **handled** (boolean) - Indicates if the event was processed. - **responseText** (string) - Message to be sent to the user. - **showAlert** (boolean) - If true, displays the response as a modal popup. #### Response Example ```json { "handled": true, "responseText": "Article published successfully", "showAlert": false } ``` ### Event Data Access Within a listener for `TelegramCallbackEvent`: - **parseCallbackData()**: Parses the callback data string (e.g., "action:id") into an associative array. - **getChatId()**: Retrieves the chat ID where the message originated. - **getMessageId()**: Retrieves the message ID of the inline keyboard. - **getFrom()**: Returns an array containing information about the user who triggered the callback. - **getRawUpdate()**: Returns the full Telegram update payload. - **setHandled(bool $handled)**: Marks the event as handled. - **setResponseText(string $text)**: Sets the text for a toast notification response. - **setShowAlert(bool $showAlert)**: Configures the response to be a modal popup alert. ``` -------------------------------- ### Bypass Git Hooks for Committing Source: https://github.com/xmon-org/notification-bundle/blob/main/CONTRIBUTING.md Commits changes while bypassing the pre-commit Git hooks. This is not recommended and should only be used in emergency situations. ```bash git commit --no-verify -m "message" ```