Skip to content

Commit 10a28a8

Browse files
authored
feat: support more image bed, support customize function name (#344)
* fix: support customize function name * fix * feat: update upload image api * feat: support more image bed * fix * fix * fix * fix
1 parent 64f7b29 commit 10a28a8

13 files changed

Lines changed: 207 additions & 65 deletions

File tree

docs/.vuepress/theme/layouts/Layout.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<!-- Twikoo -->
1515
<div id="twikoo"></div>
16-
<script src="https://cdn.jsdelivr.net/npm/twikoo@1.5.3/dist/twikoo.all.min.js" ref="twikooJs"></script>
16+
<script src="https://cdn.jsdelivr.net/npm/twikoo@1.5.4/dist/twikoo.all.min.js" ref="twikooJs"></script>
1717
</div>
1818
</template>
1919
</ParentLayout>

docs/faq.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ Akismet (Automattic Kismet) 是应用广泛的一个垃圾留言过滤系统,
114114

115115
## Vercel 无法上传图片?
116116

117-
腾讯云环境自带云存储,所以腾讯云环境下可以直接上传图片,图片保存在云存储中。然而 Vercel 环境没有,上传图片功能依赖[去不图床](https://7bu.top/),请前往 https://7bu.top/ 支持杜老师(图床作者),获得图床账号后,到管理面板中配置图床 token。
118-
119-
如果您不愿意付费,您仍可以使用杜老师提供的 [去不图床 Twikoo 专享 api token](https://github.com/imaegoo/twikoo/discussions/318),到管理面板中配置该 token、
117+
腾讯云环境自带云存储,所以腾讯云环境下可以直接上传图片,图片保存在云存储中。然而 Vercel 环境没有,上传图片功能依赖第三方图床,请在管理面板中配置图床,Twikoo 支持以下图床:
118+
119+
| 图床 | 地址 | 特点 |
120+
| ---- | ---- | ---- |
121+
| qcloud || 腾讯云环境自带,可在云开发 - 云存储中查看 |
122+
| 7bu | https://7bu.top | 去不图床,由杜老师提供支持,无免费套餐 |
123+
| smms | https://sm.ms | SMMS 图床,有免费套餐,请自行注册账号,`IMAGE_CDN_TOKEN` 可在 [Dashboard](https://sm.ms/home/apitoken) 中获取 |
124+
| [lsky-pro](https://www.lsky.pro) | 私有部署 | 兰空图床 2.0 版本,`IMAGE_CDN` 请配置图床首页 URL 地址(如 `https://test.7bu.top`),`IMAGE_CDN_TOKEN` 获取方式请参考教程 [杜老师说图床:新版本去不图床 Token 的获取与清空](https://dusays.com/454/),获取到的 token 格式应为 `1\|1bJbwlqBfnggmOMEZqXT5XusaIwqiZjCDs7r1Ob5`|

docs/quick-start.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ exports.main = require('twikoo-func').main
4444
8. 创建完成后,点击“twikoo"进入云函数详情页,进入“函数代码”标签,点击“文件 - 新建文件”,输入 `package.json`,回车
4545
9. 复制以下代码、粘贴到代码框中,点击“保存并安装依赖”
4646
``` json
47-
{ "dependencies": { "twikoo-func": "1.5.3" } }
47+
{ "dependencies": { "twikoo-func": "1.5.4" } }
4848
```
4949

5050
### 命令行部署
@@ -174,7 +174,7 @@ twikoo:
174174

175175
``` html
176176
<div id="tcomment"></div>
177-
<script src="https://cdn.jsdelivr.net/npm/twikoo@1.5.3/dist/twikoo.all.min.js"></script>
177+
<script src="https://cdn.jsdelivr.net/npm/twikoo@1.5.4/dist/twikoo.all.min.js"></script>
178178
<script>
179179
twikoo.init({
180180
envId: '您的环境id', // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app)
@@ -192,7 +192,7 @@ twikoo.init({
192192

193193
请参考爆米兔前端静态资源库 [https://cdn.baomitu.com/twikoo](https://cdn.baomitu.com/twikoo)
194194

195-
引入的 CDN 链接替换为如下即可:`https://lib.baomitu.com/twikoo/1.5.3/twikoo.all.min.js`
195+
引入的 CDN 链接替换为如下即可:`https://lib.baomitu.com/twikoo/1.5.4/twikoo.all.min.js`
196196

197197
## 开启管理面板
198198

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "twikoo",
3-
"version": "1.5.3",
3+
"version": "1.5.4",
44
"description": "A simple comment system based on Tencent CloudBase (tcb).",
55
"keywords": ["twikoojs", "comment", "comment-system", "cloudbase", "vercel"],
66
"author": "imaegoo <hello@imaegoo.com> (https://github.com/imaegoo)",

src/function/twikoo/index.js

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ exports.main = async (event, context) => {
9191
res = await commentLike(event)
9292
break
9393
case 'COMMENT_SUBMIT':
94-
res = await commentSubmit(event)
94+
res = await commentSubmit(event, context)
9595
break
9696
case 'POST_SUBMIT':
9797
res = await postSubmit(event.comment, context)
@@ -838,7 +838,7 @@ async function like (id, uid) {
838838
* @param {String} event.pid 回复的 ID
839839
* @param {String} event.rid 评论楼 ID
840840
*/
841-
async function commentSubmit (event) {
841+
async function commentSubmit (event, context) {
842842
const res = {}
843843
// 参数校验
844844
validate(event, ['url', 'ua', 'comment'])
@@ -852,7 +852,7 @@ async function commentSubmit (event) {
852852
// 异步垃圾检测、发送评论通知
853853
try {
854854
await app.callFunction({
855-
name: 'twikoo',
855+
name: context.function_name,
856856
data: { event: 'POST_SUBMIT', comment }
857857
}, { timeout: 300 }) // 设置较短的 timeout 来实现异步
858858
} catch (e) {
@@ -1396,9 +1396,9 @@ async function emailTest (event) {
13961396
const isAdminUser = await isAdmin()
13971397
if (isAdminUser) {
13981398
try {
1399-
if (!transporter) {
1400-
await initMailer({ throwErr: true })
1401-
}
1399+
// 邮件测试前清除 transporter,保证读取的是最新的配置
1400+
transporter = null
1401+
await initMailer({ throwErr: true })
14021402
const sendResult = await transporter.sendMail({
14031403
from: config.SENDER_EMAIL,
14041404
to: event.mail || config.BLOGGER_EMAIL || config.SENDER_EMAIL,
@@ -1420,21 +1420,16 @@ async function uploadImage (event) {
14201420
const { photo, fileName } = event
14211421
const res = {}
14221422
try {
1423-
if (!config.IMAGE_CDN_TOKEN) {
1423+
if (!config.IMAGE_CDN || !config.IMAGE_CDN_TOKEN) {
14241424
throw new Error('未配置图片上传服务')
14251425
}
1426-
const formData = new FormData()
1427-
formData.append('image', base64UrlToReadStream(photo, fileName))
1428-
const uploadResult = await axios.post('https://7bu.top/api/upload', formData, {
1429-
headers: {
1430-
...formData.getHeaders(),
1431-
token: config.IMAGE_CDN_TOKEN
1432-
}
1433-
})
1434-
if (uploadResult.data.code === 200) {
1435-
res.data = uploadResult.data.data
1436-
} else {
1437-
throw new Error(uploadResult.data.msg)
1426+
// tip: qcloud 图床走前端上传,其他图床走后端上传
1427+
if (config.IMAGE_CDN === '7bu') {
1428+
await uploadImageTo7Bu({ photo, fileName, config, res })
1429+
} else if (config.IMAGE_CDN === 'smms') {
1430+
await uploadImageToSmms({ photo, fileName, config, res })
1431+
} else if (isUrl(config.IMAGE_CDN)) {
1432+
await uploadImageToLskyPro({ photo, fileName, config, res })
14381433
}
14391434
} catch (e) {
14401435
console.error(e)
@@ -1444,13 +1439,75 @@ async function uploadImage (event) {
14441439
return res
14451440
}
14461441

1442+
async function uploadImageTo7Bu ({ photo, fileName, config, res }) {
1443+
// 去不图床旧版本 https://7bu.top
1444+
// TODO: 2022 年 4 月 30 日后去不图床将会升级新版本,此处逻辑要同步更新
1445+
const formData = new FormData()
1446+
formData.append('image', base64UrlToReadStream(photo, fileName))
1447+
const uploadResult = await axios.post('https://7bu.top/api/upload', formData, {
1448+
headers: {
1449+
...formData.getHeaders(),
1450+
token: config.IMAGE_CDN_TOKEN
1451+
}
1452+
})
1453+
if (uploadResult.data.code === 200) {
1454+
res.data = uploadResult.data.data
1455+
} else {
1456+
throw new Error(uploadResult.data.msg)
1457+
}
1458+
}
1459+
1460+
async function uploadImageToSmms ({ photo, fileName, config, res }) {
1461+
// SM.MS 图床 https://sm.ms
1462+
const formData = new FormData()
1463+
formData.append('smfile', base64UrlToReadStream(photo, fileName))
1464+
const uploadResult = await axios.post('https://sm.ms/api/v2/upload', formData, {
1465+
headers: {
1466+
...formData.getHeaders(),
1467+
Authorization: config.IMAGE_CDN_TOKEN
1468+
}
1469+
})
1470+
if (uploadResult.data.success) {
1471+
res.data = uploadResult.data.data
1472+
} else {
1473+
throw new Error(uploadResult.data.message)
1474+
}
1475+
}
1476+
1477+
async function uploadImageToLskyPro ({ photo, fileName, config, res }) {
1478+
// 自定义兰空图床(v2)URL
1479+
const formData = new FormData()
1480+
formData.append('file', base64UrlToReadStream(photo, fileName))
1481+
const url = `${config.IMAGE_CDN}/api/v1/upload`
1482+
let token = config.IMAGE_CDN_TOKEN
1483+
if (!token.startsWith('Bearer')) {
1484+
token = `Bearer ${token}`
1485+
}
1486+
const uploadResult = await axios.post(url, formData, {
1487+
headers: {
1488+
...formData.getHeaders(),
1489+
Authorization: token
1490+
}
1491+
})
1492+
if (uploadResult.data.status) {
1493+
res.data = uploadResult.data.data
1494+
res.data.url = res.data.links.url
1495+
} else {
1496+
throw new Error(uploadResult.data.message)
1497+
}
1498+
}
1499+
14471500
function base64UrlToReadStream (base64Url, fileName) {
14481501
const base64 = base64Url.split(';base64,').pop()
14491502
const path = `/tmp/${fileName}`
14501503
fs.writeFileSync(path, base64, { encoding: 'base64' })
14511504
return fs.createReadStream(path)
14521505
}
14531506

1507+
function isUrl (s) {
1508+
return /^http(s)?:\/\//.test(s)
1509+
}
1510+
14541511
function getAvatar (comment) {
14551512
if (comment.avatar) {
14561513
return comment.avatar

src/function/twikoo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "twikoo-func",
3-
"version": "1.5.3",
3+
"version": "1.5.4",
44
"description": "A simple comment system based on Tencent CloudBase (tcb).",
55
"author": "imaegoo <hello@imaegoo.com> (https://github.com/imaegoo)",
66
"license": "MIT",

src/js/utils/api.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const call = async (tcb, event, data = {}) => {
1010
if (_tcb) {
1111
try {
1212
return await _tcb.app.callFunction({
13-
name: 'twikoo',
13+
name: app.$twikoo.funcName || 'twikoo',
1414
data: { event, ...data }
1515
})
1616
} catch (e) {

src/js/utils/i18n/i18n.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,18 @@ const S = {
1212

1313
const pushooChannels = [
1414
'qmsg',
15-
'serverchain',
15+
'serverchan',
1616
'pushplus',
1717
'pushplushxtrip',
1818
'dingtalk',
1919
'wecom',
2020
'bark',
2121
'gocqhttp',
22+
'atri',
2223
'pushdeer',
2324
'igot',
24-
'telegram'
25+
'telegram',
26+
'feishu'
2527
].map(s => `"${s}"`)
2628

2729
const smtpServices = [
@@ -68,6 +70,24 @@ const smtpServices = [
6870
'qiye.aliyun'
6971
].map(s => `"${s}"`)
7072

73+
const highlightThemes = [
74+
'default',
75+
'coy',
76+
'dark',
77+
'funky',
78+
'okaidia',
79+
'solarizedlight',
80+
'tomorrow',
81+
'twilight'
82+
].map(s => `"${s}"`)
83+
84+
const imageBedServices = [
85+
'qcloud',
86+
'7bu',
87+
'https://test.7bu.top',
88+
'smms'
89+
].map(s => `"${s}"`)
90+
7191
/**
7292
* 把所有语言翻译放在同一对象下可以减小打包 js 的体积 (~17kb)
7393
*
@@ -320,22 +340,22 @@ export default {
320340
'Enable code highlighting. If your theme conflicts with code highlighting, please set it to false. Default: true.'
321341
],
322342
[S.ACI + '_HIGHLIGHT_THEME']: [
323-
'代码高亮主题,可选:default、coy、dark、funky、okaidia、solarizedlight、tomorrow、twilight,访问 https://prismjs.com 可预览主题效果。如果您的主题和代码高亮有冲突,请设为 none。默认:none',
324-
'代碼高亮主題,可選:default、coy、dark、funky、okaidia、solarizedlight、tomorrow、twilight,訪問 https://prismjs.com 可預覽主題效果。如果您的主題和代碼高亮有衝突,請設為 none。預設:none',
325-
'程式碼高亮主題,可選:default、coy、dark、funky、okaidia、solarizedlight、tomorrow、twilight,訪問 https://prismjs.com 可預覽主題效果。如果您的主題和程式碼高亮有衝突,請設為 none。預設:none',
326-
'Code highlighting theme. Select from: default、coy、dark、funky、okaidia、solarizedlight、tomorrow、twilight. Visit https://prismjs.com for preview. If your theme conflicts with code highlighting, please set it to none. Default: none.'
343+
`代码高亮主题,可选:${highlightThemes.join('、')},访问 https://prismjs.com 可预览主题效果。如果您的主题和代码高亮有冲突,请设为 none。默认:none`,
344+
`代碼高亮主題,可選:${highlightThemes.join('、')},訪問 https://prismjs.com 可預覽主題效果。如果您的主題和代碼高亮有衝突,請設為 none。預設:none`,
345+
`程式碼高亮主題,可選:${highlightThemes.join('、')},訪問 https://prismjs.com 可預覽主題效果。如果您的主題和程式碼高亮有衝突,請設為 none。預設:none`,
346+
`Code highlighting theme. Select from: ${highlightThemes.join(', ')}. Visit https://prismjs.com for preview. If your theme conflicts with code highlighting, please set it to none. Default: none.`
327347
],
328348
[S.ACI + '_IMAGE_CDN']: [
329-
'插入图片所使用的图床,目前支持:7bu、qcloud',
330-
'插入圖片所使用的圖床,目前支持:7bu、qcloud',
331-
'插入圖片所使用的圖床,目前支援:7bu、qcloud',
332-
'The image bed for image uploading. Select from: 7bu、qcloud'
349+
`插入图片所使用的图床,目前支持:${imageBedServices.join('、')}`,
350+
`插入圖片所使用的圖床,目前支持:${imageBedServices.join('、')}`,
351+
`插入圖片所使用的圖床,目前支援:${imageBedServices.join('、')}`,
352+
`The image bed for image uploading. Select from: ${imageBedServices.join(', ')}`
333353
],
334354
[S.ACI + '_IMAGE_CDN_TOKEN']: [
335-
'7bu 的图床 token',
336-
'7bu 的图床 token',
337-
'7bu 的图床 token',
338-
'The image bed token for 7bu.'
355+
'图床 token。qcloud 图床无需设置',
356+
'图床 token。qcloud 图床无需设置',
357+
'图床 token。qcloud 图床无需设置',
358+
'The image bed token. Unnessessary for qcloud'
339359
],
340360
[S.ACI + '_LIMIT_PER_MINUTE']: [
341361
'单个 IP 发言频率限制(条/10分钟),0 为无限制,默认:10',

src/vercel-min/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "dependencies": { "twikoo-vercel": "1.5.3" } }
1+
{ "dependencies": { "twikoo-vercel": "1.5.4" } }

0 commit comments

Comments
 (0)