Deploy on 2026-06-05 15:23:02
This commit is contained in:
116
app/Services/Notification/TelegramNotifier.php
Normal file
116
app/Services/Notification/TelegramNotifier.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Notification;
|
||||
|
||||
use Throwable;
|
||||
|
||||
class TelegramNotifier
|
||||
{
|
||||
private ?string $botToken;
|
||||
private ?string $chatId;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->botToken = $_ENV['TELEGRAM_BOT_TOKEN'] ?? null;
|
||||
$this->chatId = $_ENV['TELEGRAM_CHAT_ID'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure from database settings.
|
||||
*/
|
||||
public function configure(string $botToken, string $chatId): void
|
||||
{
|
||||
$this->botToken = $botToken;
|
||||
$this->chatId = $chatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a notification to Telegram.
|
||||
*/
|
||||
public function send(string $message, string $type = 'info'): bool
|
||||
{
|
||||
if (!$this->botToken || !$this->chatId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$icons = [
|
||||
'info' => "\xF0\x9F\x93\xA1", // 📡
|
||||
'success' => "\xE2\x9C\x85", // ✅
|
||||
'warning' => "\xE2\x9A\xA0\xEF\xB8\x8F", // ⚠️
|
||||
'error' => "\xE2\x9D\x8C", // ❌
|
||||
'opportunity' => "\xF0\x9F\x92\xA1", // 💡
|
||||
'funding' => "\xF0\x9F\x92\xB0", // 💰
|
||||
];
|
||||
|
||||
$icon = $icons[$type] ?? $icons['info'];
|
||||
$fullMessage = "{$icon} *ScoutIQ*\n\n{$message}";
|
||||
|
||||
try {
|
||||
$url = "https://api.telegram.org/bot{$this->botToken}/sendMessage";
|
||||
$payload = json_encode([
|
||||
'chat_id' => $this->chatId,
|
||||
'text' => $fullMessage,
|
||||
'parse_mode' => 'Markdown',
|
||||
'disable_web_page_preview' => true,
|
||||
]);
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
'header' => "Content-Type: application/json\r\n",
|
||||
'content' => $payload,
|
||||
'timeout' => 10,
|
||||
],
|
||||
'ssl' => ['verify_peer' => false, 'verify_peer_name' => false],
|
||||
]);
|
||||
|
||||
$response = @file_get_contents($url, false, $context);
|
||||
return $response !== false;
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify about a new opportunity.
|
||||
*/
|
||||
public function notifyNewOpportunity(array $opportunity): void
|
||||
{
|
||||
$title = $opportunity['title'] ?? 'Untitled';
|
||||
$type = $opportunity['type'] ?? 'other';
|
||||
$score = $opportunity['score'] ?? 0;
|
||||
$url = $opportunity['url'] ?? '';
|
||||
$desc = mb_substr($opportunity['description'] ?? '', 0, 200);
|
||||
$orgName = $opportunity['org_name'] ?? '';
|
||||
|
||||
$message = "*New Opportunity:* {$title}\n";
|
||||
$message .= "*Type:* {$type} | *Score:* {$score}/100\n";
|
||||
if ($orgName) $message .= "*Organization:* {$orgName}\n";
|
||||
if ($desc) $message .= "_{$desc}_\n";
|
||||
if ($url) $message .= "\n[Open Link]({$url})";
|
||||
|
||||
$this->send($message, 'opportunity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify about collector results.
|
||||
*/
|
||||
public function notifyCollectorResults(array $results): void
|
||||
{
|
||||
$message = "*Data Collection Complete*\n\n";
|
||||
$message .= "Sources: {$results['processed']}/{$results['total_sources']}\n";
|
||||
$message .= "New Opportunities: {$results['new_opportunities']}\n";
|
||||
$message .= "New Organizations: {$results['new_organizations']}\n";
|
||||
$message .= "Errors: {$results['errors']}";
|
||||
|
||||
$this->send($message, 'success');
|
||||
}
|
||||
|
||||
/**
|
||||
* Send test message.
|
||||
*/
|
||||
public function sendTest(): bool
|
||||
{
|
||||
return $this->send("Test notification from ScoutIQ. Your Telegram integration is working correctly!", 'success');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user