return [ 'enabled' => filter_var(env('TELEGRAM_ALERTS_ENABLED', false), FILTER_VALIDATE_BOOLEAN), 'bot_token' => env('TELEGRAM_BOT_TOKEN', env('TELEGRAM_BOT_API_TOKEN')), /* |-------------------------------------------------------------------------- | Chat IDs per severity channel |-------------------------------------------------------------------------- */ 'chats' => [ 'critical' => env('TELEGRAM_CHAT_CRITICAL', env('TELEGRAM_BOT_CHAT_ID')), 'ops' => env('TELEGRAM_CHAT_OPS', env('TELEGRAM_BOT_CHAT_ID')), 'revenue' => env('TELEGRAM_CHAT_REVENUE', env('TELEGRAM_BOT_CHAT_ID')), 'default' => env('TELEGRAM_BOT_CHAT_ID'), 'personal' => env('TELEGRAM_CHAT_PERSONAL'), ], 'queue' => env('TELEGRAM_ALERTS_QUEUE', 'default'), 'async' => filter_var(env('TELEGRAM_ALERTS_ASYNC', false), FILTER_VALIDATE_BOOLEAN), /** Dedupe identical alerts within N seconds */ 'dedupe_seconds' => (int) env('TELEGRAM_ALERTS_DEDUPE_SECONDS', 120), /** Max Telegram message length */ 'max_message_length' => 4000, /* |-------------------------------------------------------------------------- | Event toggles (set false to disable individual alerts) |-------------------------------------------------------------------------- */ 'events' => [ 'customer.created' => true, 'customer.registered' => true, 'admin.created' => true, 'balance.topup' => true, 'balance.manual_add' => true, 'balance.manual_remove' => true, 'campaign.created' => true, 'campaign.processing' => true, 'campaign.delivered' => true, 'campaign.failed' => true, 'campaign.paused' => true, 'campaign.stuck' => true, 'sender_id.requested' => true, 'sender_id.order_submitted' => true, 'sender_id.order_paid' => true, 'sender_id.activated' => true, 'reseller.created' => true, 'reseller.customer_registered' => true, 'ticket.created' => true, 'low_balance.customer' => true, 'low_balance.reseller' => true, 'low_balance.provider' => true, 'admin.mutation' => true, 'circuit_breaker.open' => true, 'circuit_breaker.recovered' => true, 'queue.job_failed' => true, 'application.error' => true, 'log.error' => true, ], /* |-------------------------------------------------------------------------- | UI grouping + labels for event toggles (Admin → Settings → Notifications) | Runtime overrides live in app_config.telegram_event_toggles (JSON). |-------------------------------------------------------------------------- */ 'event_groups' => [ 'revenue' => [ 'label' => 'Revenue & balances', 'help' => 'Platform customer and reseller inventory top-ups are alerted. Reseller-owned customer top-ups are never sent to Telegram.', 'events' => [ 'balance.topup' => 'M-Pesa / payment top-ups', 'balance.manual_add' => 'Manual SMS credit added', 'balance.manual_remove' => 'Manual SMS credit removed', ], ], 'accounts' => [ 'label' => 'Accounts', 'help' => null, 'events' => [ 'customer.created' => 'Admin created customer', 'customer.registered' => 'Customer self-registration', 'admin.created' => 'New administrator', 'reseller.created' => 'New reseller', 'reseller.customer_registered' => 'Reseller registered a customer', ], ], 'campaigns' => [ 'label' => 'Campaigns', 'help' => null, 'events' => [ 'campaign.created' => 'Campaign created', 'campaign.processing' => 'Campaign started', 'campaign.delivered' => 'Campaign completed', 'campaign.failed' => 'Campaign failed', 'campaign.paused' => 'Campaign paused', 'campaign.stuck' => 'Campaign stuck processing', ], ], 'sender_ids' => [ 'label' => 'Sender IDs', 'help' => null, 'events' => [ 'sender_id.requested' => 'Sender ID requested', 'sender_id.order_submitted' => 'Sender ID order submitted', 'sender_id.order_paid' => 'Sender ID order paid', 'sender_id.activated' => 'Sender ID activated', ], ], 'ops' => [ 'label' => 'Ops & reliability', 'help' => null, 'events' => [ 'ticket.created' => 'Support ticket opened', 'low_balance.customer' => 'Customer low balance', 'low_balance.reseller' => 'Reseller low inventory', 'low_balance.provider' => 'Provider low balance', 'admin.mutation' => 'Admin configuration change', 'circuit_breaker.open' => 'SMS provider circuit open', 'circuit_breaker.recovered' => 'SMS provider recovered', 'queue.job_failed' => 'Background job failed', 'application.error' => 'Application error', 'log.error' => 'Log error (laravel.log)', ], ], ], /* |-------------------------------------------------------------------------- | Map ActivityLog events → Telegram occurrence keys |-------------------------------------------------------------------------- */ 'activity_log_map' => [ \App\Models\ActivityLog::EVENT_CUSTOMER_CREATED => 'customer.created', \App\Models\ActivityLog::EVENT_ADMIN_CREATED => 'admin.created', \App\Models\ActivityLog::EVENT_BALANCE_ADDED_MANUAL => 'balance.manual_add', \App\Models\ActivityLog::EVENT_BALANCE_ADDED_PAYMENT => 'balance.topup', \App\Models\ActivityLog::EVENT_INVOICE_TOPUP => 'balance.topup', \App\Models\ActivityLog::EVENT_BALANCE_REMOVED => 'balance.manual_remove', \App\Models\ActivityLog::EVENT_ADMIN_IMPERSONATION => 'admin.mutation', \App\Models\ActivityLog::EVENT_CAMPAIGN_CREATED => 'campaign.created', \App\Models\ActivityLog::EVENT_CAMPAIGN_DELIVERED => 'campaign.delivered', \App\Models\ActivityLog::EVENT_CAMPAIGN_FAILED => 'campaign.failed', \App\Models\ActivityLog::EVENT_CAMPAIGN_PROCESSING => 'campaign.processing', \App\Models\ActivityLog::EVENT_CAMPAIGN_PAUSED => 'campaign.paused', \App\Models\ActivityLog::EVENT_TICKET_CREATED => 'ticket.created', \App\Models\ActivityLog::EVENT_SENDER_ID_REQUESTED => 'sender_id.requested', \App\Models\ActivityLog::EVENT_SENDER_ID_ORDER_SUBMITTED => 'sender_id.order_submitted', \App\Models\ActivityLog::EVENT_SENDER_ID_ORDER_PAID => 'sender_id.order_paid', \App\Models\ActivityLog::EVENT_SENDER_ID_ACTIVATED => 'sender_id.activated', \App\Models\ActivityLog::EVENT_RESELLER_CREATED => 'reseller.created', \App\Models\ActivityLog::EVENT_RESELLER_CUSTOMER_REGISTERED => 'reseller.customer_registered', \App\Models\ActivityLog::EVENT_USER_SELF_REGISTERED => 'customer.registered', ], /* |-------------------------------------------------------------------------- | Severity → chat channel |-------------------------------------------------------------------------- */ 'severity_channels' => [ 'critical' => 'critical', 'warning' => 'ops', 'revenue' => 'revenue', 'info' => 'default', ], /* |-------------------------------------------------------------------------- | Admin mutation middleware: route name patterns to skip (noise) |-------------------------------------------------------------------------- */ 'admin_mutation_exclude' => [ '*search*', '*export*', '*avatar*', 'admin.notifications.*', 'admin.communication.stats', 'admin.settings.check_update', 'admin.settings.telegram', 'admin.settings.telegram.test', 'admin.telegram-alerts.*', // Balance changes already emit balance.manual_add / balance.manual_remove. 'admin.customers.add_unit', 'admin.customers.remove_unit', ], 'stuck_campaign_minutes' => (int) env('TELEGRAM_STUCK_CAMPAIGN_MINUTES', 30), /* |-------------------------------------------------------------------------- | Laravel log → Telegram (Log::error and above) |-------------------------------------------------------------------------- */ 'log_levels' => ['error', 'critical', 'alert', 'emergency'], /** Skip log lines already reported as uncaught exceptions (Handler). */ 'log_skip_exception_logged' => true, /** Substrings to ignore in log messages (avoid loops / noise). */ 'log_exclude_patterns' => [ 'TelegramAlertService', 'ActivityLogObserver: Telegram alert failed', 'NotifyTelegramOnLogError', ], ];