219 lines
6.3 KiB
PHP
219 lines
6.3 KiB
PHP
<?php
|
|
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
|
header("Cache-Control: post-check=0, pre-check=0", false);
|
|
header("Pragma: no-cache");
|
|
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
// ==================== CONFIGURATION ====================
|
|
// Replace with your bot token from @BotFather
|
|
$apiToken = "YOUR_BOT_TOKEN_HERE";
|
|
|
|
// Channel IDs - replace with your actual channel IDs
|
|
$channelId = "YOUR_CHANNEL_ID"; // Example: -1001234567890
|
|
|
|
// RSS feeds to monitor - add your feeds here
|
|
// Format: ["RSS_URL", "INSTANT_VIEW_HASH"] (leave second parameter empty if no instant view)
|
|
$rssFeeds = [
|
|
["https://example1.com/feed/",""],
|
|
["https://example2.com/feed/","YOUR_INSTANT_VIEW_HASH"]
|
|
];
|
|
|
|
// ==================== END CONFIGURATION ====================
|
|
|
|
// Files for state management
|
|
$stateFile = 'rss_state.json';
|
|
$logFile = 'rss_log.txt';
|
|
|
|
$formattedMessages = [];
|
|
|
|
// Load previous state to avoid duplicate messages
|
|
$previousState = file_exists($stateFile) ? json_decode(file_get_contents($stateFile), true) : [];
|
|
|
|
// Array to store all news to send to channel
|
|
$allNews = [];
|
|
|
|
// Get today's date
|
|
$todayDate = date('Y-m-d');
|
|
// Uncomment next line for testing yesterday's news
|
|
// $todayDate = date('Y-m-d', strtotime('-1 day'));
|
|
|
|
writeToLog("Script started for date: " . $todayDate);
|
|
|
|
// Process each RSS feed
|
|
foreach ($rssFeeds as $feed) {
|
|
list($url, $instantView) = $feed;
|
|
|
|
// Check if URL has already been processed today
|
|
if (isset($previousState[$url][$todayDate])) {
|
|
$sentLinks = $previousState[$url][$todayDate];
|
|
} else {
|
|
$sentLinks = [];
|
|
}
|
|
|
|
// Read and filter today's news for each RSS feed
|
|
$newItems = readAndFilterRSS($url, $instantView, $todayDate, $sentLinks);
|
|
|
|
// Add news to channel only if there are unsent items
|
|
if (!empty($newItems)) {
|
|
$allNews = array_merge($allNews, $newItems);
|
|
|
|
// Update sent news with new links only
|
|
$previousState[$url][$todayDate] = array_merge($sentLinks, getNewsLinks($newItems));
|
|
}
|
|
|
|
// Log processing results
|
|
$itemCount = is_array($newItems) ? count($newItems) : 0;
|
|
writeToLog("Feed: $url, New items: " . $itemCount);
|
|
}
|
|
|
|
// Clean up old state data (remove previous days)
|
|
if ($previousState) {
|
|
foreach ($previousState as $url => $dates) {
|
|
foreach ($dates as $date => $links) {
|
|
if ($date !== $todayDate) {
|
|
unset($previousState[$url][$date]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Save updated state
|
|
file_put_contents($stateFile, json_encode($previousState));
|
|
}
|
|
|
|
// Send news to Telegram channel
|
|
if (!empty($formattedMessages)) {
|
|
writeToLog("Sending " . count($formattedMessages) . " messages to Telegram");
|
|
sendToTelegram($formattedMessages);
|
|
} else {
|
|
writeToLog("No new messages to send");
|
|
}
|
|
|
|
writeToLog("Script completed");
|
|
|
|
/**
|
|
* Write message to log file with timestamp
|
|
*/
|
|
function writeToLog($txt)
|
|
{
|
|
global $logFile;
|
|
$timestamp = date('[Y-m-d H:i:s]');
|
|
$logMessage = $timestamp . ' ' . $txt . "\n";
|
|
error_log($logMessage, 3, $logFile);
|
|
}
|
|
|
|
/**
|
|
* Read and filter today's news from RSS feed
|
|
*/
|
|
function readAndFilterRSS($url, $instantView, $targetDate, $sentLinks)
|
|
{
|
|
global $formattedMessages;
|
|
|
|
try {
|
|
// Load RSS feed using SimpleXML
|
|
$feed = simplexml_load_file($url);
|
|
if ($feed === false) {
|
|
writeToLog('Error: Failed to load RSS feed - ' . $url);
|
|
throw new Exception('Failed to load RSS feed: ' . $url);
|
|
}
|
|
|
|
$channelTitle = (string)$feed->channel->title;
|
|
$newItems = [];
|
|
|
|
// Process each item in the feed
|
|
foreach ($feed->channel->item as $item) {
|
|
$pubDate = new DateTime($item->pubDate);
|
|
|
|
// Check if news is from target date and hasn't been sent already
|
|
if ($pubDate->format('Y-m-d') == $targetDate && !in_array((string)$item->link, $sentLinks)) {
|
|
$newItems[] = [
|
|
'title' => (string)$item->title,
|
|
'link' => (string)$item->link,
|
|
];
|
|
|
|
// Prepare formatted message for Telegram
|
|
$formattedMessages[] = prepareTelegramMessage($item, $instantView, $channelTitle);
|
|
}
|
|
}
|
|
|
|
return $newItems;
|
|
|
|
} catch (Exception $e) {
|
|
writeToLog('Error processing RSS feed: ' . $e->getMessage());
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extract links from news array
|
|
*/
|
|
function getNewsLinks($news)
|
|
{
|
|
return array_map(function ($item) {
|
|
return $item['link'];
|
|
}, $news);
|
|
}
|
|
|
|
/**
|
|
* Send messages to Telegram channel
|
|
*/
|
|
function sendToTelegram($messages)
|
|
{
|
|
global $channelId, $apiToken;
|
|
|
|
foreach ($messages as $message) {
|
|
$data = [
|
|
'chat_id' => $channelId,
|
|
'text' => $message[0],
|
|
'parse_mode' => "HTML",
|
|
];
|
|
|
|
$response = file_get_contents("https://api.telegram.org/bot$apiToken/sendMessage?" . http_build_query($data));
|
|
|
|
if ($response !== false && $response !== "") {
|
|
writeToLog('Message sent successfully: ' . $message[1]);
|
|
} else {
|
|
writeToLog('Failed to send message: ' . $message[1]);
|
|
// Wait before retry
|
|
sleep(2);
|
|
}
|
|
}
|
|
|
|
writeToLog('Total messages sent to Telegram channel: ' . count($messages));
|
|
}
|
|
|
|
/**
|
|
* Prepare formatted message for Telegram
|
|
*/
|
|
function prepareTelegramMessage($item, $instantView, $channelTitle)
|
|
{
|
|
$itemTitle = (string)$item->title;
|
|
$itemLink = (string)$item->link;
|
|
$itemDesc = (string)$item->description;
|
|
$itemDesc = strip_tags($itemDesc, "<b>,<i>,<a>,<strong>,<em>");
|
|
$itemPubDate = (string)$item->pubDate;
|
|
$timestamp = strtotime($itemPubDate);
|
|
$pubDate = date("d/m/Y", $timestamp);
|
|
|
|
$message = "";
|
|
|
|
// Add instant view if available
|
|
if ($instantView !== "") {
|
|
$instViewUrl = "https://t.me/iv?url=" . $itemLink . "&rhash=" . $instantView;
|
|
$invisibleUrl = "<a href='$instViewUrl'>‌</a>";
|
|
$message .= $invisibleUrl;
|
|
}
|
|
|
|
// Format message
|
|
$message .= "Source: <i><b>" . $channelTitle . "</b> - " . $pubDate . "</i>" . PHP_EOL;
|
|
$message .= PHP_EOL;
|
|
$message .= "<b>" . $itemTitle . "</b>" . PHP_EOL;
|
|
$message .= $itemDesc . PHP_EOL;
|
|
$message .= PHP_EOL;
|
|
$message .= $itemLink;
|
|
|
|
return [$message, $itemTitle];
|
|
}
|