Initial commit: delta-chat-bot
This commit is contained in:
commit
8f47610133
10 changed files with 3603 additions and 0 deletions
99
php-proxy/rss.php
Normal file
99
php-proxy/rss.php
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* Telegram RSS Proxy with cache
|
||||
*
|
||||
* GET /rss.php?channel=CHANNEL&limit=N
|
||||
* or via .htaccess rewrite: /rss/CHANNEL?limit=N
|
||||
*
|
||||
* Returns RSS XML from local cache (if fresh) or proxies from tg.i-c-a.su.
|
||||
* Enclosure URLs are rewritten to go through media.php for local caching.
|
||||
* Cache files are pre-rewritten so cache hits avoid DOMDocument entirely.
|
||||
*/
|
||||
|
||||
define('CACHE_DIR', __DIR__ . '/cache');
|
||||
define('TG_BASE', 'https://tg.i-c-a.su');
|
||||
define('PROXY_BASE', 'https://proxy.budaev.org');
|
||||
define('UA', 'Mozilla/5.0 (compatible; ProxyBot/1.0)');
|
||||
define('CACHE_TTL', 600);
|
||||
|
||||
$channel = preg_replace('/[^a-zA-Z0-9_]/', '', $_GET['channel'] ?? '');
|
||||
if (!$channel) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
echo 'Missing channel parameter';
|
||||
exit;
|
||||
}
|
||||
|
||||
$limit = min(max((int)($_GET['limit'] ?? 10), 1), 100);
|
||||
|
||||
// Staggered TTL: vary per channel to avoid mass expiration
|
||||
$stagger = crc32($channel) % 300;
|
||||
$ttl = CACHE_TTL + $stagger;
|
||||
|
||||
// Non-standard limits: fetch directly, no caching
|
||||
if ($limit !== 10) {
|
||||
$xml = fetchFeed($channel, $limit, true);
|
||||
if ($xml === null) {
|
||||
header('HTTP/1.1 502 Bad Gateway');
|
||||
echo 'Failed to fetch feed';
|
||||
exit;
|
||||
}
|
||||
header('Content-Type: application/rss+xml; charset=utf-8');
|
||||
echo $xml;
|
||||
exit;
|
||||
}
|
||||
|
||||
$cacheFile = CACHE_DIR . '/' . $channel . '.xml';
|
||||
|
||||
// Cache hit — pre-rewritten, no DOMDocument needed
|
||||
if (file_exists($cacheFile) && filemtime($cacheFile) > time() - $ttl) {
|
||||
header('Content-Type: application/rss+xml; charset=utf-8');
|
||||
readfile($cacheFile);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Cache miss or stale — fetch and rewrite in one DOMDocument pass
|
||||
$xml = fetchFeed($channel, $limit, false);
|
||||
if ($xml === null) {
|
||||
// Serve stale cache if available
|
||||
if (file_exists($cacheFile)) {
|
||||
header('Content-Type: application/rss+xml; charset=utf-8');
|
||||
readfile($cacheFile);
|
||||
exit;
|
||||
}
|
||||
// No cache at all — return empty feed so bot doesn't fall back to tg.i-c-a.su
|
||||
header('Content-Type: application/rss+xml; charset=utf-8');
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>' . htmlspecialchars($channel) . '</title></channel></rss>';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Save pre-rewritten XML to cache
|
||||
file_put_contents($cacheFile, $xml);
|
||||
|
||||
header('Content-Type: application/rss+xml; charset=utf-8');
|
||||
echo $xml;
|
||||
|
||||
|
||||
function fetchFeed(string $channel, int $limit, bool $skipRewrite): ?string {
|
||||
$url = TG_BASE . '/rss/' . $channel . '?limit=' . $limit;
|
||||
$ctx = stream_context_create(['http' => ['timeout' => 30, 'user_agent' => UA, 'follow_location' => true]]);
|
||||
$raw = @file_get_contents($url, false, $ctx);
|
||||
if (!$raw) return null;
|
||||
|
||||
if ($skipRewrite) {
|
||||
return $raw;
|
||||
}
|
||||
|
||||
// Parse DOM once, rewrite enclosures, return pre-rewritten XML
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadXML($raw);
|
||||
if (!$doc->documentElement) return null;
|
||||
|
||||
foreach ($doc->getElementsByTagName('enclosure') as $enc) {
|
||||
$encUrl = $enc->getAttribute('url');
|
||||
if (strpos($encUrl, TG_BASE) !== false) {
|
||||
$enc->setAttribute('url', PROXY_BASE . '/media.php?url=' . urlencode($encUrl));
|
||||
}
|
||||
}
|
||||
|
||||
return $doc->saveXML();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue