Typecho定时获取FreshRSS订阅数据

最近许多小伙伴都添加了RSS功能实现订阅其他博客的更新内容,不用再一个一个点进对方网站查看是否有更新。之前我一直使用“Feeder”软件来订阅我感兴趣的博客,现在有了这个方法就赶紧搞上,以下是我的折腾记录。

FreshRSS安装与配置

新建网站,因为FreshRSS是PHP程序,所以直接下载上传到新建网站的根目录。

配置网站的运行目录,将运行目录设置为/p

访问网站进行安装FreshRSS。

进入后台,在“设置-管理-认证”开启允许api。在“设置-账户-账户管理-API管理”设置密码并提交保存,记住设置的api密码。

Typecho配置

在Typecho站点根目录下创建一个php文件,用于放FreshRSS api调用函数,例如:rss.php,内容:

<?php
/**
 * 获取最新订阅文章并生成JSON文件
 */
function getAllSubscribedArticlesAndSaveToJson($user, $password)
{
    $apiUrl = 'https://你部署FreshRSS的域名/api/greader.php';
    $loginUrl = $apiUrl . '/accounts/ClientLogin?Email=' . urlencode($user) . '&Passwd=' . urlencode($password);
    $loginResponse = curlRequest($loginUrl);
    if (strpos($loginResponse, 'Auth=') !== false) {
        $authToken = substr($loginResponse, strpos($loginResponse, 'Auth=') + 5);
        $articlesUrl = $apiUrl . '/reader/api/0/stream/contents/reading-list?&n=1000';
        $articlesResponse = curlRequest($articlesUrl, $authToken);
        $articles = json_decode($articlesResponse, true);
        if (isset($articles['items'])) {
            usort($articles['items'], function ($a, $b) {
                return $b['published'] - $a['published'];
            });
            $subscriptionsUrl = $apiUrl . '/reader/api/0/subscription/list?output=json';
            $subscriptionsResponse = curlRequest($subscriptionsUrl, $authToken);
            $subscriptions = json_decode($subscriptionsResponse, true);
            if (isset($subscriptions['subscriptions'])) {
                $subscriptionMap = array();
                foreach ($subscriptions['subscriptions'] as $subscription) {
                    $subscriptionMap[$subscription['id']] = $subscription;
                }
                $formattedArticles = array();
                foreach ($articles['items'] as $article) {
                    $desc_length = mb_strlen(strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8')), 'UTF-8');
                    if ($desc_length > 20) {
                        $short_desc = mb_substr(strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8')), 0, 99, 'UTF-8') . '...';
                    } else {
                        $short_desc = strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8'));
                    }
                    
                    $formattedArticle = array(
                        'site_name' => $article['origin']['title'],
                        'title' => $article['title'],
                        'link' => $article['alternate'][0]['href'],
                        'time' => date('Y-m-d', $article['published']),
                        'description' => $short_desc,
                    );

                    $subscriptionId = $article['origin']['streamId'];
                    if (isset($subscriptionMap[$subscriptionId])) {
                        $subscription = $subscriptionMap[$subscriptionId];
                        $iconUrl = $subscription['iconUrl'];
                        $filename = 'https://你部署FreshRSS的域名/'.substr($iconUrl, strrpos($iconUrl, '/') + 1);
                        $formattedArticle['icon'] = $filename;
                    }

                    $formattedArticles[] = $formattedArticle;
                }

                saveToJsonFile($formattedArticles);
                return $formattedArticles;
            } else {
                echo 'Error retrieving articles.';
            }
        } else {
            echo 'Error retrieving articles.';
        }
    } else {
        echo 'Login failed.';
    }
    return null;
}
function curlRequest($url, $authToken = null)
{
    $ch = curl_init($url);
    if ($authToken) {
        $headers = array(
            'Authorization: GoogleLogin auth=' . $authToken,
        );
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}
/**
 * 将数据保存到JSON文件中
 */
function saveToJsonFile($data)
{
    $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    file_put_contents('output.json', $json);
    echo '数据已保存到JSON文件中';
}

// 调用函数并提供用户名和密码
getAllSubscribedArticlesAndSaveToJson('这里是FreshRSS的用户名', '这里是设置的api密码');

获取到数据之后在你博客需要显示订阅数据的地方插入以下代码:

<?php
// 判断JSON数据是否存在且可读
if (is_writeable('./output.json')) {
    // 获取JSON数据
    $jsonData = file_get_contents('./output.json');
    // 将JSON数据解析为PHP数组
    $articles = json_decode($jsonData, true);
    // 对文章按时间排序(最新的排在前面)
    usort($articles, function ($a, $b) {
return strtotime($b['time']) - strtotime($a['time']);
    });
    // 设置每页显示的文章数量
    $itemsPerPage = 20;
    // 生成文章列表
    foreach (array_slice($articles, 0, $itemsPerPage) as $article) {
//以下代码请根据主题自定义
        $articles_list ='
        图标:' . htmlspecialchars($article['icon']) . '
        站点标题:' . htmlspecialchars($article['site_name']) . '
        文章标题:' . htmlspecialchars($article['title']) . '
        文章内容摘要:' . htmlspecialchars($article['description']) . '
        文章链接:' . htmlspecialchars($article['link']) . '
        文章发布时间:' . htmlspecialchars($article['time']) . '
        ';
        echo $articles_list;
//自定义结束
    }
}
;?>

以上代码须根据自己主题进行自定义。

自动更新

想要RSS自动刷新,还需要定时访问PHP文件,可以使用宝塔的计划任务来实现,依据自己需求,设置执行周期即可,执行代码如下,具体路径请依照自己的绝对路径设置。

FreshRSS定时更新(shell脚本):

php /www/wwwroot/yourdomain.com/app/actualize_script.php > /tmp/FreshRSS.log 2>&1

Typecho定时获取数据(定时访问URL):

Typecho博客地址/rss.php

最后,去FreshRSS管理后台添加你要订阅的博客就行了。

参考

  1. https://yefengs.com/2854.html
  2. https://dai.ge/124.html

> 快来说说你的想法吧~