资讯专栏INFORMATION COLUMN

基于 github issues 实现第三方评论系统

waltr / 2083人阅读

摘要:什么是第三方评论系统博客或系统,一般都是有内容和评论两部分组成。而且垃圾评论和过滤非法关键字难度较大,所以在国内外都有第三评论系统。三评论系统实现预备工作创建。

本文只是介绍如何基于 github issues 实现第三方评论系统,对于 Hexo 介绍,本文并不打算详述,如果有童鞋之前还没有了解 Hexo 的,可以先看一下之前文章《静态博客框架 Hexo 入门 》,或者直接访问 Hexo 官网 https://hexo.io/

一、事情起因

个人博客是基于静态博客系统(Hexo)搭建的,本身是没有具备任何后台功能的,例如搜索、评论系统等。但是,如果你想在静态博客上加上评论功能,也不是无法实现的,这时候就要借助第三方评论系统了。

什么是第三方评论系统?博客或 cms 系统,一般都是有内容和评论两部分组成。评论可以增加博主与用户之间的交流互动,也是博主一对多的传达自己想法和观点的交流平台。所以除了社区平台外,评论也成为一般博客和cms系统必备功能。大型网站本身自己开发了评论系统和分享系统,而一般中小型网站开发的自己的评论系统,成本高。而且垃圾评论和过滤非法关键字难度较大,所以在国内外都有第三评论系统。以下是曾经流行或者正在流行的一些第三方评论系统。

多说。多说是一款追求极致体验的社会化评论框,可以用微博、QQ、人人、豆瓣等帐号登录并评论。多说已经成为国内份额最大的所谓“社交评论框”服务,但是这个行业第一并没有给它带来更多的收益和发展空间。不过可惜,现在已经停止服务了。

搜狐畅言。搜狐畅言是由搜狐推出的一个简单而强大的社会化评论及聚合平台。用户可以直接用自己的社会化网络账户在第三方网站发表评论,并且一键评论同步至社交网络将网站内容和自己的评论分享给好友。增加第三方网站用户活跃度,调动好友参与评论,帮助网站实现社会化网络优化,有效提升网站社会化流量。现在还健在。

友言。友言是国内专业的第三方实时社会化评论系统,“完全社交化”可将评论一键同步到各大微博与社区(目前支持10个社交媒体),同时将评论的回复与跟帖同步至使用的网站上,让网站变得更具有活力和社交性,从而为网站带来更多的回访和流量,是一个简单而强大的社会化评论及聚合平台。现在还健在。

网易云跟帖。网易云跟贴是网易公司推出的强大而又简单的评论聚合与分享平台。坑爹的,在多说发布停止服务声明之后不久,网易云跟帖也分出了停止服务声明。

Disqus。说到第三放评论系统,当然不得不提国外第三方评论系统界的老大 Disqus,只可惜由于天朝网络原因,Disqus 加载很慢,甚至有时候加载不出来,建议用户自备梯子。

那么回归主题,市面上那么多第三方评论系统,就算有那么一两个挂掉了,还是有很多选择呢,为什么还要自己去做一个呢,这不是造轮子吗?其实,一开始我一直用多说的,用的不亦乐乎,突然有一天说挂就挂了,没办法,那我就选择其他的呗,然后就改成网易云,坑爹的,刚改造好没多久,网易云也挂了。

后面我就在网上找啊找啊,发现居然有人用 GitHub Issue 做了一个评论系统,这无疑是一个很好的想法,很有创意啊。当然,我也拿来用了,但是始终觉得有点丑,跟我自己的博客主题不搭,才用了两天,撤了,打算自己做一个。说干就干,程序员总喜欢造轮子。

二、什么是 GitHub Issues

经常逛 GitHub 的童鞋,都应该知道这个功能,有人理解 GitHub 的 issue 功能,就如同 TODO list。你可以把所有想要在下一步完成的工作,如 feature 添加、bug 修复等,都写成一个个的 issue ,放在上面。既可以作为提醒,也可以统一管理。另外,每一次 commit 都可以选择性的与某个 issue 关联。比如在 message 中添加 #n,就可以与第 n 个 issue 进行关联。具体可以看一下知乎里面别人对 《github issue是做什么的? 》的解答。而本博客的评论数据存储 issues 仓库地址为 https://github.com/jangdelong/blog_comments/issues,仓库里面并没有放置托管代码。总之,像我现在要用 github Issues 来制作评论系统的,其实就是把数据存储到 github issues,简单的说可以把 github issues 理解为一个免费的数据库。

三、评论系统实现

预备工作

创建 OAuth applications。评论需要涉及 GitHub 授权登录,所以在这里你先要有一个 GitHub application。GitHub 授权登录遵循 OAuth 2.0 标准。OAuth applications 创建如下图所示,填写上面相应的内容。

Application name:你的站点名称;
Homepage URL:你的站点主页链接;
Application description:站点描述;
Authorization callback URL:GitHub 授权成功后返回地址

创建成功之后会生成一个 Client ID 和一个 Client Secret。

GitHub REST API v3

GitHub 提供了很多方便第三方开发的 API,当然,github issues 的增删改查 API 也在其中,有了这些 API,你才能各种施展奇技淫巧,比如我们现在要写的评论系统。另外,有人怀疑我们应不应该“滥用”这些 API,但是,个人觉得,既然,GitHub 提供了这些 API,就是说明要开放给大家这些权限,应该就不怕你“滥用”。那么,要满足我们现在的需求需要哪些 API 呢,下面我列举一下,以我的账号为例,jangdelong 为 Github 名,blog_comments 为仓库名。

GET: https://api.github.com/repos/jangdelong/blog_comments/issues 获取所有issues信息

GET: https://api.github.com/repos/jangdelong/blog_comments/issues/11 获取某个issue下的信息 (11 为 issue 编号 )

GET: https://api.github.com/repos/jangdelong/blog_comments/issues/11/comments 获取某个issue下的评论

GET: https://api.github.com/repos/jangdelong/blog_comments/issues/comments/111/reactions 获取评论 ID 为 111 下的所有 reactions(reactions 包含顶[+1]、踩[-1]、喜欢[heart]等字段)

POST: https://api.github.com/repos/jangdelong/blog_comments/issues 创建一个 issue

POST: https://api.github.com/repos/jangdelong/blog_comments/issues/11/comments 在编号为 11 的 issue 下创建一条评论

POST: https://api.github.com/repos/jangdelong/blog_comments/issues/comments/111/reactions 在 ID 为 111 的评论下创建一条 reactions(如 heart)

POST:https://developer.github.com/v3/markdown/ markdown 语法解析接口

整体设计

流程图:

                                             |--> 显示已登录    
                              |--> 已登录 --> |--> 加载评论列表 --> 分页加载 
                              |              |--> 其他 
                              |              |--> 评论操作 --> 成功/失败            |
 开始 --> GitHub 授权登录 ? --> |                                                   |--> 结束
                              |              |--> 显示未登录                       |
                              |--> 未登录 --> |--> 加载评论列表 --> 分页加载          
                                             |--> 其他
                                             |--> 评论操作 --> 提示未登录状态

效果图:

因此,我们可以将评论系统分为列表(list)、评论框(box)、顶部登录状态栏(signbar)等部分。View 部分的代码组织为:

// 为了减少全局变量,整个网站就暴露一个全局变量 JELON
var JELON = JELON || {};
;(function (JL) {
    ...
    JL.Renders = {
        // 列表模块
        list: {
            tpl: ...,
            ...
        },
        // 评论框模块
        box: {
            tpl: ...,
            ...
        },
        // 顶部登录状态栏
        signBar: {
            tpl: ...,
            ...
        },
        ... // 其他模块视图
    };
    ...
})(JELON);

视图部分的代码组织好之后,根据 GitHub 提供的各种 API,我们将其封装到 Requests 里面去,组织如下:

// 为了减少全局变量,整个网站就暴露一个全局变量 JELON
var JELON = JELON || {};
;(function (JL) {
    ...
    JL.Requests = {
        // 根据 label 获取 issue 编号
        getIssueNumberByLabel: function () { ... },
        // 创建 issue
        createIssue: function () { ... },
        // 根据 issue 编号获取评论列表
        getCommentListByIssueNumber: function () { ... },
        // 根据评论 ID 获取 reactions (即点赞数据)
        getReactionsByCommentId: function () { ... },
        // markdown 解析
        markdown: function () { ... },
        // 通过 code 获取 access_token
        getAccessToken: function () { ... },
        // 利用 access_token 去获取 GitHub 用户信息
        getUserInfo: function () { ... },
        // 创建评论
        createComment: function () { ... },
        // 创建 reactions (点赞)
        createReaction: function () { ... }
    };
    ...
})(JELON);

接下来是封装事件操作,我们将其封装到 Actions 里面去,代码组织如下:

// 为了减少全局变量,整个网站就暴露一个全局变量 JELON
var JELON = JELON || {};
;(function (JL) {
    ...
    JL.Actions = {
        // 初始加载,如列表、登录状态等
        init: function () { ... },
        // 登出操作
        signOut: function () { ... },
        // 列表翻页跳转
        pageJump: function () { ... },
        // 编辑预览
        editPreviewSwitch: function () { ... },
        // 提交评论操作
        postComment: function () { ... },
        // 点赞操作
        like: function () { ... }
    };
    ...
})(JELON);

程序入口:

// 为了减少全局变量,整个网站就暴露一个全局变量 JELON
var JELON = JELON || {};
;(function (JL) {
    ...
    JL.Comment = function (options) {
        JL.options = options || {};
        $("comments").innerHTML = [
            this.Renders.signBar.tpl,
            this.Renders.box.tpl,
            this.Renders.tips,
            this.Renders.list.tpl
        ].join("");
        JL.Actions.init();
    };
    ...
})(JELON);

登录流程

GitHub 授权登录是不可或缺的功能,用只有登录之后才能进行评论。前面有提到,GitHub 授权登录是遵循一个 OAuth 2.0 标准。以下是 OAuth 2.0 的一个运作流程,可以让我们更好的理解它。

那么,GitHub 授权登录是怎么样按照这个标准来运作的呢,接下来简单介绍一下,如果要更加详细深入了解的话,你也可以访问 GitHub 官方文档。

用户发起重定向请求授权服务器换取 code

`GET http://github.com/login/oauth/authorize`

拿到 code 之后,利用 client_id、client_secret 和 code 去换取 token_access。(client_id 和 client_secret 前面的预备工作里有提到)

`POST https://github.com/login/oauth/access_token`

获取到 token_access 之后,我们就可以用 token_access 去获取已登录的用户的信息了

`GET https://api.github.com/user`

通过以上3个步骤,GitHub 授权登录就算是完成了。

四、评论系统如何使用

引入评论系统相关的 css、js 。引入相关样式和脚本之后,在你的页面加入以下代码:



由于这个评论系统是要集成到个人的主题上去的,所以要跟 hexo-theme-xups 搭配使用,hexo-theme-xups 主题链接为 https://github.com/jangdelong/hexo-theme-xups,目前最新的主题(带有GitHub 登录评论功能),后面会更新上去,往后当然也会陆续进行更新和优化,欢迎多多 star。

五、遇到的问题

遇到的问题主要有三个,一个是创建 label 权限问题,一个是跨域问题,另外一个 GitHub 授权登录兼容性问题。

创建 label 权限问题(目前未解决)。label 是一个连接文章和 issue 关系的纽带,因为我们要用 label 去查询 issue number,后面的流程才能走下去。如今遇到的问题是,对于新文章来说,只能是我自己本人账号(GitHub Application)创建者才能创建带有 label 的 issue。参考了 GitHub 的接口(POST /repos/:owner/:repo/issues)文档,上面说

> Labels to associate with this issue. NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise.

跨域问题(暂时解决了)。主要是通过 code 去换取 token_access 的 POST https://github.com/login/oauth/access_token 这个接口跨域,暂时解决方案是
使用 https://cors-anywhere.herokuapp.com/https://github.com/login/oauth/access_token 进行转发。参见:https://github.com/Rob--W/cor... 。

GitHub 授权登录兼容性问题(暂时不解决)。经过简单的测试,发现 PC 端兼容性问题主要是一些老版本的浏览器,其中包括一些老版本的谷歌浏览器(版本号55.x.xxxx.xx);而移动端的主要是 UC 浏览器无法实现 GitHub 授权登录。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88501.html

相关文章

  • Gitalk评论插件使用教程

    摘要:说明是一个基于和开发的评论插件。默认值类型布尔值,选填,类似评论框的全屏遮罩效果。默认值类型布尔值,选填,如果当前页面没有相应的且登录的用户属于,则会自动创建。参考类型布尔值,选填,启用快捷键提交评论。 1. 说明 Gitalk 是一个基于 GitHub Issue 和 Preact 开发的评论插件。 Gitalk 的特性: 1、使用 GitHub 登录2、支持多语言 [en, zh-...

    孙吉亮 评论0 收藏0
  • 为什么我选择用 Github issues 来写博客

    摘要:为什么不选择其他方案在文章的开头我有提到,我曾经尝试过用,,自行搭建服务等途径去尝试维护博客。但这些尝试的结果均不合我意,最后无疾而终。我们使用作为博客平台,也就是相当于管理后端。 showImg(https://segmentfault.com/img/remote/1460000019265125?w=700&h=420); 对于爱写东西的人来说,挑一个合适的博客平台是非常重要的。...

    Scliang 评论0 收藏0
  • 为什么我选择用 Github issues 来写博客

    摘要:为什么不选择其他方案在文章的开头我有提到,我曾经尝试过用,,自行搭建服务等途径去尝试维护博客。但这些尝试的结果均不合我意,最后无疾而终。我们使用作为博客平台,也就是相当于管理后端。showImg(https://user-gold-cdn.xitu.io/2019/5/22/16adf79473dbdf59); 对于爱写东西的人来说,挑一个合适的博客平台是非常重要的。而作为一个 Web 开发...

    gnehc 评论0 收藏0
  • GitHub Issue取代多说,是不是很厉害?

    摘要:摘要别了,多说,拥抱。年月日,多说正式下线,这多少让人感觉有些遗憾。其中,必须填写博客的域名我填的是。注册成功之后将获取与,后面将会用到。但是这些是不存在的,因此需要通过初始化去创建。这一点比较麻烦,因为对于每一篇博客都需要进行初始化。 摘要: 别了,多说,拥抱Gitment。 2017年6月1日,多说正式下线,这多少让人感觉有些遗憾。在比较了多个博客评论系统,我最终选择了Gitmen...

    awokezhou 评论0 收藏0
  • 基于Symfony开发的PHP内容社区系统PHPDish

    摘要:是一个基于框架开发的内容社区系统得益于大量的前端以及后端的第三方类库的使用使得有着高质量的代码,敏捷实现由于目前规划了很多碎片化的功能因此没有采取标准的代码版本的概念你可以使用或者直接下载本仓库进行程序的安装。其它功能可以联系本人定制。 showImg(https://segmentfault.com/img/remote/1460000011969909); PHPDish 是一个基...

    Donne 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<