Files
RSS-To-Telegram-Bot/rss-to-telegram-bot.php
2025-07-08 19:12:05 +02:00

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'>&#8204</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];
}