{"id":17967632,"url":"https://github.com/DesertsP/Valine-Admin","last_synced_at":"2025-03-25T08:31:24.419Z","repository":{"id":40680460,"uuid":"100242299","full_name":"DesertsP/Valine-Admin","owner":"DesertsP","description":"🔥A simple comment system based on LeanCloud and Valine. ","archived":false,"fork":false,"pushed_at":"2022-12-06T19:11:40.000Z","size":4024,"stargazers_count":715,"open_issues_count":46,"forks_count":472,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-29T15:49:13.894Z","etag":null,"topics":["akismet","comments","leancloud","leanengine","nodejs"],"latest_commit_sha":null,"homepage":"https://deserts.io/valine-admin-document/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DesertsP.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-14T07:53:10.000Z","updated_at":"2024-10-28T07:54:29.000Z","dependencies_parsed_at":"2023-01-23T15:15:12.911Z","dependency_job_id":null,"html_url":"https://github.com/DesertsP/Valine-Admin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DesertsP%2FValine-Admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DesertsP%2FValine-Admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DesertsP%2FValine-Admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DesertsP%2FValine-Admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DesertsP","download_url":"https://codeload.github.com/DesertsP/Valine-Admin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245426260,"owners_count":20613319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["akismet","comments","leancloud","leanengine","nodejs"],"created_at":"2024-10-29T14:09:11.832Z","updated_at":"2025-03-25T08:31:23.349Z","avatar_url":"https://github.com/DesertsP.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"Valine Admin 是 [Valine 评论系统](https://deserts.io/diy-a-comment-system/)的扩展和增强，主要实现评论邮件通知、评论管理、垃圾评论过滤等功能。支持完全自定义的邮件通知模板。基于Akismet API实现准确的垃圾评论过滤。此外，使用云函数等技术解决了免费版云引擎休眠问题，支持云引擎自动唤醒，漏发邮件自动补发。兼容云淡风轻及Deserts维护的多版本Valine。\n\n\u003e NOTE: **该项目基于LeanCloud云引擎示例代码实现，您可以自由地复制和修改。包含了一些 trick 实现资源的最大化利用 ，但请勿滥用免费资源。引用本说明文档及Deserts博客上的相关文章务必注明来源。**\n\n[评论在线演示及相关功能测试](https://panjunwen.github.io/Valine/)\n\n## 相关项目\n\n评论框前端：[Valine on Github](https://github.com/DesertsP/Valine)\n\n[Disqus2LeanCloud数据迁移](https://github.com/DesertsP/disqus2valine/)\n\n\n\n## 云引擎\"一键\"部署\n\n进入评论系统数据库所在的LeanCloud应用。进入「云引擎-设置」，设置环境变量以及云引擎域名。**以下参数需要正确设置。云引擎域名（ADMIN_URL参数）用于评论后台管理，如[](https://deserts-io.avosapps.us/) 。\n\n\n变量 | 示例 | 说明\n--- | ------ | ---------\nSITE_NAME | Deserts | [必填]博客名称\nSITE_URL  | https://panjunwen.com | [必填]首页地址 \n**SMTP_SERVICE** | QQ | [新版支持]邮件服务提供商，支持 QQ、163、126、Gmail 以及 [更多](https://nodemailer.com/smtp/well-known/#supported-services) \nSMTP_USER | xxxxxx@qq.com | [必填]SMTP登录用户\nSMTP_PASS | ccxxxxxxxxch | [必填]SMTP登录密码（QQ邮箱需要获取独立密码） \nSENDER_NAME | Deserts | [必填]发件人 \nSENDER_EMAIL | xxxxxx@qq.com | [必填]发件邮箱\nADMIN_URL | https://xxx.leanapp.cn/ | [建议]Web主机二级域名（云引擎域名），用于自动唤醒 \nBLOGGER_EMAIL | xxxxx@gmail.com | [可选]博主通知收件地址，默认使用SENDER_EMAIL\nAKISMET_KEY | xxxxxxxx | [可选]Akismet Key 用于垃圾评论检测，设为MANUAL_REVIEW开启人工审核，留空不使用反垃圾\n\n![](assets/imgs/envs.png)\n\n切换到「云引擎-部署」，部署模式选择「部署项目-Git部署」，分支「master」，手动部署目标环境为「生产环境」在[Leancloud](https://leancloud.cn/dashboard/#/apps)云引擎设置界面，填写代码库并保存：https://github.com/DesertsP/Valine-Admin.git，即可一键部署。\n\n![deploy3](assets/imgs/deploy4.png)\n\n## 评论管理\n\n首先需要设置管理员信息。访问管理员注册页面`https://云引擎域名/sign-up`，注册管理员登录信息，如：[https://deserts-io.avosapps.us/sign-up](https://deserts-io.avosapps.us/sign-up) \n\n![signup](assets/imgs/signup2.png)\n\n\n- 注：使用原版Valine如果遇到注册页面不显示直接跳转至登录页的情况，请手动删除_User表中的全部数据。\n## 定时任务设置\n\n关于自动休眠的官方说法：[点击查看](https://leancloud.cn/docs/leanengine_plan.html#hash633315134)。目前实现了两种云函数定时任务来解决云引擎休眠的问题：\n\n- 自动唤醒，定时访问Web APP二级域名防止云引擎休眠；\n- 每天定时检查过去24小时内漏发的邮件通知。\n\n进入「云引擎-定时任务」，创建两个定时任务。\n\n![](assets/imgs/cron4.png)\n\n\n选择self-wake云函数，Cron表达式为`0 */30 0-16 * * ?`，表示每天早0点到晚16点每隔30分钟访问云引擎。\n\n选择resend-mails云函数，Cron表达式为`0 0 0 * * ?`，表示每天0点检查过去24小时内漏发的通知邮件并补发。\n\n- [关于国际版时区的问题](https://github.com/DesertsP/Valine-Admin/issues/63#issuecomment-533784574)：国际版使用UTC-0时间，注意与国内时间对应。\n\n**至此，Valine Admin 已经可以正常工作，以下是可选配置。**\n\n------------------\n\n## 更多设置\n\n#### 邮件通知模板\n\n邮件通知模板在云引擎环境变量中设定，可自定义通知邮件标题及内容模板。\n\n环境变量 | 示例 | 说明\n--- | ------ | ------\nMAIL_SUBJECT | ${PARENT_NICK}，您在${SITE_NAME}上的评论收到了回复 | [可选]@通知邮件主题（标题）模板\nMAIL_TEMPLATE | 见下文 | [可选]@通知邮件内容模板\nMAIL_SUBJECT_ADMIN | ${SITE_NAME}上有新评论了 | [可选]博主邮件通知主题模板\nMAIL_TEMPLATE_ADMIN | 见下文 | [可选]博主邮件通知内容模板\n\n\n邮件通知包含两种，分别是被@通知和博主通知，这两种模板都可以完全自定义。默认使用经典的蓝色风格模板（样式来源未知）。\n\n默认被@通知邮件内容模板如下：\n\n```html\n\u003cdiv style=\"border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;\"\u003e\u003ch2 style=\"border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;\"\u003e您在\u003ca style=\"text-decoration:none;color: #12ADDB;\" href=\"${SITE_URL}\" target=\"_blank\"\u003e            ${SITE_NAME}\u003c/a\u003e上的评论有了新的回复\u003c/h2\u003e ${PARENT_NICK} 同学，您曾发表评论：\u003cdiv style=\"padding:0 12px 0 12px;margin-top:18px\"\u003e\u003cdiv style=\"background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;\"\u003e            ${PARENT_COMMENT}\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e${NICK}\u003c/strong\u003e回复说：\u003c/p\u003e\u003cdiv style=\"background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;\"\u003e ${COMMENT}\u003c/div\u003e\u003cp\u003e您可以点击\u003ca style=\"text-decoration:none; color:#12addb\" href=\"${POST_URL}\" target=\"_blank\"\u003e查看回复的完整內容\u003c/a\u003e，欢迎再次光临\u003ca style=\"text-decoration:none; color:#12addb\" href=\"${SITE_URL}\" target=\"_blank\"\u003e${SITE_NAME}\u003c/a\u003e。\u003cbr\u003e\u003c/p\u003e\u003c/div\u003e\u003c/div\u003e\n```\n\n效果如下图：\n\n![mail-blue-template](assets/imgs/wei-ming-ming.png)\n\n@通知模板中的可用变量如下（注，这是邮件模板变量，是指嵌入到HTML邮件模板中的变量，请勿与云引擎环境变量混淆）：\n\n模板变量 | 说明\n----|----\nSITE_NAME | 博客名称\nSITE_URL | 博客首页地址\nPOST_URL | 文章地址（完整路径）\nPARENT_NICK | 收件人昵称（被@者，父级评论人）\nPARENT_COMMENT | 父级评论内容\nNICK | 新评论者昵称\nCOMMENT | 新评论内容\n\n\n默认博主通知邮件内容模板如下：\n\n```html\n\u003cdiv style=\"border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;\"\u003e\u003ch2 style=\"border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;\"\u003e您在\u003ca style=\"text-decoration:none;color: #12ADDB;\" href=\"${SITE_URL}\" target=\"_blank\"\u003e${SITE_NAME}\u003c/a\u003e上的文章有了新的评论\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e${NICK}\u003c/strong\u003e回复说：\u003c/p\u003e\u003cdiv style=\"background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;\"\u003e ${COMMENT}\u003c/div\u003e\u003cp\u003e您可以点击\u003ca style=\"text-decoration:none; color:#12addb\" href=\"${POST_URL}\" target=\"_blank\"\u003e查看回复的完整內容\u003c/a\u003e\u003cbr\u003e\u003c/p\u003e\u003c/div\u003e\u003c/div\u003e\n```\n\n博主通知邮件模板中的可用变量与@通知中的基本一致，**```PARENT_NICK``` 和 ```PARENT_COMMENT``` 变量不再可用。**\n\n\n这里还提供一个彩虹风格的@通知邮件模板代码：\n\n```html\n\u003cdiv style=\"border-radius: 10px 10px 10px 10px;font-size:13px;    color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);\"\u003e\u003cdiv style=\"width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;\"\u003e\u003cp style=\"font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;\"\u003e您在\u003ca style=\"text-decoration:none;color: #ffffff;\" href=\"${SITE_URL}\"\u003e ${SITE_NAME}\u003c/a\u003e上的留言有新回复啦！\u003c/p\u003e\u003c/div\u003e\u003cdiv style=\"margin:40px auto;width:90%\"\u003e\u003cp\u003e${PARENT_NICK} 同学，您曾在文章上发表评论：\u003c/p\u003e\u003cdiv style=\"background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;\"\u003e${PARENT_COMMENT}\u003c/div\u003e\u003cp\u003e${NICK} 给您的回复如下：\u003c/p\u003e\u003cdiv style=\"background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;\"\u003e${COMMENT}\u003c/div\u003e\u003cp\u003e您可以点击\u003ca style=\"text-decoration:none; color:#12addb\" href=\"${POST_URL}#comments\"\u003e查看回复的完整內容\u003c/a\u003e，欢迎再次光临\u003ca style=\"text-decoration:none; color:#12addb\"                href=\"${SITE_URL}\"\u003e ${SITE_NAME}\u003c/a\u003e。\u003c/p\u003e\u003cstyle type=\"text/css\"\u003ea:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}\u003c/style\u003e\u003c/div\u003e\u003c/div\u003e\n```\n\n效果如图：\n\n![彩虹模板](assets/imgs/rainbow-theme.png)\n\n\n#### 垃圾评论检测\n\n\u003e Akismet (Automattic Kismet)是应用广泛的一个垃圾留言过滤系统，其作者是大名鼎鼎的WordPress 创始人 Matt Mullenweg，Akismet也是WordPress默认安装的插件，其使用非常广泛，设计目标便是帮助博客网站来过滤留言Spam。有了Akismet之后，基本上不用担心垃圾留言的烦恼了。\n\u003e 启用Akismet后，当博客再收到留言会自动将其提交到Akismet并与Akismet上的黑名单进行比对，如果名列该黑名单中，则该条留言会被标记为垃圾评论且不会发布。\n\n如果还没有Akismet Key，你可以去 [AKISMET FOR DEVELOPERS 免费申请一个](https://akismet.com/development/)；\n**当AKISMET_KEY设为MANUAL_REVIEW时，开启人工审核模式；**\n如果你不需要反垃圾评论，Akismet Key 环境变量可以忽略。\n\n**为了实现较为精准的垃圾评论识别，采集的判据除了评论内容、邮件地址和网站地址外，还包括评论者的IP地址、浏览器信息等，但仅在云引擎后台使用这些数据，确保隐私和安全。**\n\n**如果使用了本站最新的Valine和Valine Admin，并设置了Akismet Key，可以有效地拦截垃圾评论。被标为垃圾的评论可以在管理页面取消标注。**\n\n环境变量 | 示例 | 说明\n--- | ------ | ------\nAKISMET_KEY | xxxxxxxxxxxx | [可选]Akismet Key 用于垃圾评论检测\n\n#### 手动配置邮件服务器\n\n- 自定义邮件服务器地址和端口信息，删除SMTP_SERVICE环境变量，新增以下变量：\n\n变量 | 示例 | 说明\n----|------|------\nSMTP_HOST | smtp.qq.com | [可选]SMTP_SERVICE留空时，自定义SMTP服务器地址 \nSMTP_PORT | 465 | [可选]SMTP_SERVICE留空时，自定义SMTP端口\nSMTP_SECURE | true | [可选]使用TLS \n\n\n### Troubleshooting\n\n- 部署失败，请在评论中附图，或去Github发起Issue\n- 邮件发送失败，确保环境变量都没问题后，重启云引擎\n    ![重启云引擎](assets/imgs/reboot.png)\n- 博主通知模板中不要出现`PARENT*`相关参数（请勿混用模板）\n- 点击邮件中的链接跳转至相应评论，这一细节实现需要在Web前端添加一点额外的代码：\n``` javascript\n\u003cscript\u003e\n    if(window.location.hash){\n        var checkExist = setInterval(function() {\n           if ($(window.location.hash).length) {\n              $('html, body').animate({scrollTop: $(window.location.hash).offset().top-90}, 1000);\n              clearInterval(checkExist);\n           }\n        }, 100);\n    }\n\u003c/script\u003e\n```\n\n\n\n------------------\n\n## 开发者文档\n\n**以下内容仅用于 LeanEngine 开发，普通用户无需理会**\n\n首先确认本机已经安装 [Node.js](http://nodejs.org/) 运行环境和 [LeanCloud 命令行工具](https://leancloud.cn/docs/leanengine_cli.html)，然后执行下列指令：\n\n```\n$ git clone https://github.com/DesertsP/Valine-Admin.git\n$ cd Valine-Admin\n```\n\n安装依赖：\n\n```\nnpm install\n```\n\n登录并关联应用：\n\n```\nlean login\nlean switch\n```\n\n启动项目：\n\n```\nlean up\n```\n\n之后你就可以在 [localhost:3000](http://localhost:3000) 访问到你的应用了。\n\n部署到预备环境（若无预备环境则直接部署到生产环境）：\n```\nlean deploy\n```\n\n## License\n\n[MIT License](https://github.com/panjunwen/LeanComment/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDesertsP%2FValine-Admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDesertsP%2FValine-Admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDesertsP%2FValine-Admin/lists"}