Add rss-to-telegram-bot.php
This commit is contained in:
218
rss-to-telegram-bot.php
Normal file
218
rss-to-telegram-bot.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?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];
|
||||
}
|
Reference in New Issue
Block a user