跟风利用FreshRSS实现朋友圈

段先森 折腾3443字数 5244阅读17分28秒阅读模式

前言

最开始我用的是阿锋的朋友圈插件,这是我第一次见把友链整合到RSS订阅把它展现出来,那会儿很好奇,就使用了阿锋的晨风自定义插件。后面看到了hexo-circle-of-friends,网上找了半天没看到WordPress上面实现的方法。后面才看到了若志的这篇文章,索性就搞了起来。

实现步骤

首先要搭建FreshRSS,这个教程很多,我使用的是服务器搭建,纯宝塔操作,简单不复杂。文章源自段先森-https://www.duanxiansen.com/1354.html

1、添加站点,注意:需要确认已经安装了 PHP 扩展 fileinfo(我的默认安装了)。接下来在宝塔面板创建新站点,设置好数据库与 PHP 版本。数据库我选择的是mysql,PHP版本是0。然后,删去网站根目录下默认添加创建的所有文件,确保文件夹全部清空。打开站点根目录,把 FreshRSS 源代码上传到网站根目录,域名访问开始安装。文章源自段先森-https://www.duanxiansen.com/1354.html

2、安装完成后进入设置-账户-API 管理,填写api密码提交。文章源自段先森-https://www.duanxiansen.com/1354.html

3、进入设置-认证,勾选允许 API 访问 (用于手机应用),提交。文章源自段先森-https://www.duanxiansen.com/1354.html

4、添加你的友链feed地址,我试了一下,直接输入友链域名大部分的rss地址可以自动获取,少部分不知道rss地址的可以安装浏览器插件查看或者问博主本人。文章源自段先森-https://www.duanxiansen.com/1354.html

5、不知道是不是我安装的有问题,点击添加的友链管理,会弹出502 Bad Gateway nginx。不过双击还是就进去了,可以进行删除修改等操作,凑合着用吧。文章源自段先森-https://www.duanxiansen.com/1354.html

6、在自己站点根目录下创建一个php文件,用于放FreshRSS api调用函数,例如:rss.php。访问https://你的博客域名/rss.php,显示数据已保存到JSON文件中。文章源自段先森-https://www.duanxiansen.com/1354.html

<?php
/**
 * 获取最新订阅文章并生成JSON文件
 */
function getAllSubscribedArticlesAndSaveToJson($user, $password)
{
    $apiUrl = 'https://你部署FreshRSS的域名/p/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 H:i', $article['published']),
                        'description' => $short_desc,
                    );

                    $subscriptionId = $article['origin']['streamId'];
                    if (isset($subscriptionMap[$subscriptionId])) {
                        $subscription = $subscriptionMap[$subscriptionId];
                        $iconUrl = $subscription['iconUrl'];
                        $filename = 'https://你部署FreshRSS的域名/p/'.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的用户名', '这里是第3步设置的api密码');

注意:'https://你部署FreshRSS的域名/p/,没证书是http(最好带上证书,不然图标获取不到),还有后面的/p/. 新建页面,在正文里面输入简码:文章源自段先森-https://www.duanxiansen.com/1354.html

7、我是用的是添加页面使用简码将其显示出来,在子主题的funtions.php里添加以下代码:文章源自段先森-https://www.duanxiansen.com/1354.html

// 在 functions.php 中添加 shortcode 函数
function display_articles_shortcode() {
    // 获取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 = 30;

    // 生成文章列表
    ob_start(); // 开始缓存输出
    foreach (array_slice($articles, 0, $itemsPerPage) as $article) {
    ?>
        <div class="article">
            <h3>
                <img src="<?php echo htmlspecialchars($article['icon']); ?>" alt="Icon" class="icon">
                <a href="<?php echo htmlspecialchars($article['link']); ?>" target="_blank"><?php echo htmlspecialchars($article['title']); ?></a>
            </h3>
            <p>作者:<?php echo htmlspecialchars($article['site_name']); ?></p>
            <p><?php echo htmlspecialchars($article['description']); ?></p>
            <time><?php echo htmlspecialchars($article['time']); ?></time>
        </div>
    <?php
    }
    return ob_get_clean(); // 返回缓存的输出并清除缓存
}

// 注册简码
add_shortcode('display_articles', 'display_articles_shortcode');

8、可以自定义css样式让其精致的显示,这是我的css代码:文章源自段先森-https://www.duanxiansen.com/1354.html

/* Article container */
.article {
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 15px;
    margin-bottom: 20px;
}

/* Article title */
.article h3 {
    margin-top: 0;
}

/* Article icon */
.icon {
    width: 50px;
    height: 50px;
    margin-right: 10px;
    border-radius: 50%;
}

/* Article metadata */
.article p, .article time {
    margin: 5px 0;
}

/* Article time */
.article time {
    font-style: italic;
}

/* Hover effect on article */
.article:hover {
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    transition: box-shadow 0.3s ease;
}
/* Article icon */
.icon {
    width: 1.5em; /* 使用 em 单位可以根据标题字体大小调整图标大小 */
    height: auto; /* 自动调整高度以保持宽高比 */
    margin-right: 10px;
    vertical-align: middle; /* 垂直居中对齐 */
    border-radius: 50%;
}

9、在宝塔添加一个计划任务,定时访问执行第6步创建的php文件,以更新订阅数据。官网里说的那个自动刷新订阅源的方法,我按照官网设置了每隔30分钟刷新,不知道咋回事儿不管用,每次都要自己刷新后才更新订阅源。

结语

自己部署rss订阅源是一件非常有成就感的事儿,过程也是艰辛,尤其是我这种不会代码的,更是辛苦,一步一步地查看错误,幸好有GPT,帮我可以查找问题,解决问题,不至于求人。

 最后更新:2024-4-8
段先森
  • 本文由 段先森 发表于 2024年3月12日16:17:18
  • 转载请务必保留本文链接:https://www.duanxiansen.com/1354.html
博客圈
评论  34  访客  22  作者  12
    • Pipu
      Pipu 2

      我在你的基础上新增了两个功能,哈哈哈哈,欢迎体验:https://pipuwong.com/friend-link-to-moments

      • Pipu
        Pipu 2

        问了GPT,等博主更新代码。

        GPT:
        根据您提供的主题的 functions.php 文件内容,错误信息指出问题出现在 usort() 函数的第一个参数必须是数组,但实际传入的是 null。这可能是因为从 output.json 文件中读取的数据为空或无法解析为有效的数组,导致在排序时出现问题。

        为了解决这个问题,您可以按照以下步骤进行操作:

        检查 output.json 文件:

        确保 output.json 文件存在于正确的路径,并且包含有效的 JSON 数据。
        检查文件路径是否正确,并且 PHP 有权限读取该文件。
        处理 JSON 数据:

        在读取和解析 JSON 数据之前,最好添加一些错误处理代码,以确保数据有效性。
        您可以使用 json_last_error() 和 json_last_error_msg() 函数来检查 JSON 解析过程中是否发生了错误,并根据需要进行处理。
        处理空数据情况:

        如果 output.json 中的数据为空,或者无法解析为有效的数组,您可能需要添加适当的错误处理代码来处理这种情况。
        可以在解析数据之后检查数组是否为空,避免将空数组传递给 usort() 函数。
        调试排序逻辑:

        您可以添加一些调试语句来输出读取的 JSON 数据以及排序后的数组,以便更好地了解问题所在。
        可以在 usort() 函数调用之前输出 $articles 数组,以确保它包含有效的数据。
        备份并测试修改:

        在对 functions.php 文件进行任何更改之前,请确保先备份文件。
        对修改后的代码进行测试,确保问题得到解决,并且没有引入新的错误。
        通过以上步骤,您应该能够解决 Caards Child 主题中 usort() 函数导致的错误问题。

        • Pipu
          Pipu 2

          插入主题functions.php以后,是可以显示好友文案饿了,但是一点击编辑页面,就出现错误哦:此站点遇到了致命错误,请查看您站点管理员电子邮箱中收到的邮件来获得指引。

          错误提示位置在 :

          // 对文章按时间排序(最新的排在前面)
          usort($articles, function ($a, $b) {
          return strtotime($b[‘time’]) – strtotime($a[‘time’]);
          });

          请问如何解决哦?

            • 段先森
              段先森

              @ Pipu 我的好像没遇到过,我研究研究

            • Pipu
              Pipu 2

              你好,搭建完了。但是有一个问题,左边的图片出不来,请问是什么情况?
              https://img.gugu.ovh/i/2024/04/17/132903.webp

                • 段先森
                  段先森

                  @ Pipu 调用的图标没出来,是没开启ssl嘛

                    • Pipu
                      Pipu 2

                      @ 段先森 已经可以了。要去地址栏 输入域名/rss.php

                    • Pipu
                      Pipu 2

                      @ Pipu 已解决。

                    • 段先森
                      段先森

                      要不是张老师提醒,我都不知道,这篇文章缺少部分代码,现已更新

                      • 大雄
                        大雄 1

                        是个什么高端的操作.

                        • 大峰
                          大峰 3

                          这个很方便啊,我都是一个个打开网站去看的~

                          • 格子老师
                            格子老师 3

                            另外,我看大家目前都是直接读取api 没考虑把api的数据记录到数据库,然后就可以实现分页展示历史文章了。前台再增加代码检测网址可用性 不可用的,前台也就不展示了。

                              • 格子老师
                                格子老师 3

                                @ 格子老师 另外,跳转链接 没设置成新窗口打开,不便于自己页面的留存。

                                • 格子老师
                                  格子老师 3

                                  @ 格子老师 保存到自己数据库后,还可以前台使用代码读取对应文章ID 然后通过读取到的ID 获取文章链接 这个操作的同时,还能记录该篇文章的点击次数,这样又可以实现本地的点击排行 或者阅读排行什么的。 也算是增加功能了,反正是折腾。

                                • 粽叶加米
                                  粽叶加米 3

                                  真不错,FreshRSS有api功能,之前很多博友安利过,我就本地安装试了一下,很方便实用。

                                  • 格子老师
                                    格子老师 3

                                    这个模板 看着不错啊

                                      • 段先森
                                        段先森

                                        @ 格子老师 哈哈,格子老师,你的博客咋样了,还是没好嘛

                                          • 格子老师
                                            格子老师 3

                                            @ 段先森 还是有端口号 但一直正常运行着呢 没有关闭

                                        • maqingxi
                                          maqingxi 2

                                          这个功能看着就特别帅,如果能读取缩略图就更完美了。

                                          • 老张博客
                                            老张博客 4

                                            这也是我想折腾的事。

                                              • 段先森
                                                段先森

                                                @ 老张博客 张老师再完美一下 :oops:

                                                • 格子老师
                                                  格子老师 3

                                                  @ 老张博客 缩略图 好像有一个网站能通过网址自动生成 我之前记着的没找到 但是百度搜索 有好多

                                                • HWL
                                                  HWL 1

                                                  不错!以前也找过类似解决方案,找不到放弃了

                                                    • 段先森
                                                      段先森

                                                      @ HWL 那就再尝试尝试呗

                                                    • 梦不见的梦
                                                      梦不见的梦 2

                                                      我的订阅不知道为啥总是出现些莫名其妙的问题,就是别人网站更新了我订阅获取不到 :zhuakuang:

                                                        • 段先森
                                                          段先森

                                                          @ 梦不见的梦 我一般都是自己更新订阅源,我看了一下,慢慢的就全了,

                                                        • obaby
                                                          obaby 2

                                                          哦吼,又一个朋友圈~~

                                                            • 段先森
                                                              段先森

                                                              @ obaby 我看了一下你的,好复杂,不会弄,哈哈

                                                            • 林羽凡
                                                              林羽凡 6

                                                              你正在朝大佬的路上靠近,哈哈哈

                                                            匿名

                                                            发表评论

                                                            匿名网友
                                                            :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
                                                            确定

                                                            取消

                                                            拖动滑块以完成验证