twikoo-vercel 1.4.3 → 1.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/api/index.js +83 -19
  2. package/package.json +1 -1
package/api/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Twikoo vercel function v1.4.3
2
+ * Twikoo vercel function v1.4.7
3
3
  * (c) 2020-present iMaeGoo
4
4
  * Released under the MIT License.
5
5
  */
@@ -27,7 +27,7 @@ const window = new JSDOM('').window
27
27
  const DOMPurify = createDOMPurify(window)
28
28
 
29
29
  // 常量 / constants
30
- const VERSION = '1.4.3'
30
+ const VERSION = '1.4.7'
31
31
  const RES_CODE = {
32
32
  SUCCESS: 0,
33
33
  NO_PARAM: 100,
@@ -123,6 +123,9 @@ module.exports = async (requestArg, responseArg) => {
123
123
  case 'GET_RECENT_COMMENTS': // >= 0.2.7
124
124
  res = await getRecentComments(event)
125
125
  break
126
+ case 'EMAIL_TEST': // >= 1.4.6
127
+ res = await emailTest(event)
128
+ break
126
129
  default:
127
130
  if (event.event) {
128
131
  res.code = RES_CODE.EVENT_NOT_EXIST
@@ -177,6 +180,7 @@ async function connectToDatabase (uri) {
177
180
  if (db) return db
178
181
  if (!uri) throw new Error('未设置环境变量 MONGODB_URI')
179
182
  // If no connection is cached, create a new one
183
+ console.log('Connecting to database...')
180
184
  const client = await MongoClient.connect(uri, {
181
185
  useNewUrlParser: true,
182
186
  useUnifiedTopology: true
@@ -185,6 +189,7 @@ async function connectToDatabase (uri) {
185
189
  // using the database path of the connection string
186
190
  db = await client.db((new URL(uri)).pathname.substr(1))
187
191
  // Cache the database connection and return the connection
192
+ console.log('Connected to database')
188
193
  return db
189
194
  }
190
195
 
@@ -577,13 +582,19 @@ function jsonParse (content) {
577
582
 
578
583
  // Valine 导入
579
584
  async function commentImportValine (valineDb, log) {
580
- if (!valineDb || !valineDb.results) {
585
+ let arr
586
+ if (valineDb instanceof Array) {
587
+ arr = valineDb
588
+ } else if (valineDb && valineDb.results) {
589
+ arr = valineDb.results
590
+ }
591
+ if (!arr) {
581
592
  log('Valine 评论文件格式有误')
582
593
  return
583
594
  }
584
595
  const comments = []
585
- log(`共 ${valineDb.results.length} 条评论`)
586
- for (const comment of valineDb.results) {
596
+ log(`共 ${arr.length} 条评论`)
597
+ for (const comment of arr) {
587
598
  try {
588
599
  const parsed = {
589
600
  _id: comment.objectId,
@@ -835,12 +846,19 @@ async function commentSubmit (event) {
835
846
  res.id = comment.id
836
847
  // 异步垃圾检测、发送评论通知
837
848
  try {
838
- await axios.post(`${request.headers['x-forwarded-proto']}://${request.headers.host}`, {
839
- event: 'POST_SUBMIT',
840
- comment
841
- }, { headers: { 'x-twikoo-recursion': 'true' }, timeout: 300 }) // 设置较短的 timeout 来实现异步
842
- } catch (e) {
843
849
  console.log('开始异步垃圾检测、发送评论通知')
850
+ console.time('POST_SUBMIT')
851
+ await Promise.race([
852
+ axios.post(`https://${process.env.VERCEL_URL}`, {
853
+ event: 'POST_SUBMIT',
854
+ comment
855
+ }, { headers: { 'x-twikoo-recursion': 'true' } }),
856
+ // 如果超过 5 秒还没收到异步返回,直接继续,减少用户等待的时间
857
+ new Promise((resolve) => setTimeout(resolve, 5000))
858
+ ])
859
+ console.timeEnd('POST_SUBMIT')
860
+ } catch (e) {
861
+ console.log('POST_SUBMIT 失败', e)
844
862
  }
845
863
  return res
846
864
  }
@@ -872,13 +890,14 @@ async function sendNotice (comment) {
872
890
  noticeReply(comment),
873
891
  noticeWeChat(comment),
874
892
  noticePushPlus(comment),
893
+ noticeWeComPush(comment),
875
894
  noticeQQ(comment)
876
895
  ]).catch(console.error)
877
896
  return { code: RES_CODE.SUCCESS }
878
897
  }
879
898
 
880
899
  // 初始化邮件插件
881
- async function initMailer () {
900
+ async function initMailer ({ throwErr = false } = {}) {
882
901
  try {
883
902
  if (!config || !config.SMTP_USER || !config.SMTP_PASS) {
884
903
  throw new Error('数据库配置不存在')
@@ -899,13 +918,16 @@ async function initMailer () {
899
918
  throw new Error('SMTP 服务器没有配置')
900
919
  }
901
920
  transporter = nodemailer.createTransport(transportConfig)
902
- transporter.verify(function (error, success) {
903
- if (error) throw new Error('SMTP 邮箱配置异常:', error)
904
- else if (success) console.log('SMTP 邮箱配置正常')
905
- })
921
+ try {
922
+ const success = await transporter.verify()
923
+ if (success) console.log('SMTP 邮箱配置正常')
924
+ } catch (error) {
925
+ throw new Error('SMTP 邮箱配置异常:', error)
926
+ }
906
927
  return true
907
928
  } catch (e) {
908
929
  console.error('邮件初始化异常:', e.message)
930
+ if (throwErr) throw e
909
931
  return false
910
932
  }
911
933
  }
@@ -917,7 +939,8 @@ async function noticeMaster (comment) {
917
939
  const IM_PUSH_CONFIGS = [
918
940
  'SC_SENDKEY',
919
941
  'QM_SENDKEY',
920
- 'PUSH_PLUS_TOKEN'
942
+ 'PUSH_PLUS_TOKEN',
943
+ 'WECOM_API_URL'
921
944
  ]
922
945
  // 判断是否存在即时消息推送配置
923
946
  const hasIMPushConfig = IM_PUSH_CONFIGS.some(item => !!config[item])
@@ -1008,6 +1031,21 @@ async function noticePushPlus (comment) {
1008
1031
  console.log('pushplus 通知结果:', sendResult)
1009
1032
  }
1010
1033
 
1034
+ // 自定义WeCom企业微信api通知
1035
+ async function noticeWeComPush (comment) {
1036
+ if (!config.WECOM_API_URL) {
1037
+ console.log('未配置 WECOM_API_URL,跳过企业微信推送')
1038
+ return
1039
+ }
1040
+ if (config.BLOGGER_EMAIL === comment.mail) return
1041
+ const SITE_URL = config.SITE_URL
1042
+ const WeComContent = config.SITE_NAME + '有新评论啦!🎉🎉' + '\n\n' + '@' + comment.nick + '说:' + $(comment.comment).text() + '\n' + 'E-mail: ' + comment.mail + '\n' + 'IP: ' + comment.ip + '\n' + '点此查看完整内容:' + appendHashToUrl(comment.href || SITE_URL + comment.url, comment.id)
1043
+ const WeComApiContent = encodeURIComponent(WeComContent)
1044
+ const WeComApiUrl = config.WECOM_API_URL
1045
+ const sendResult = await axios.get(WeComApiUrl + WeComApiContent)
1046
+ console.log('WinxinPush 通知结果:', sendResult)
1047
+ }
1048
+
1011
1049
  // QQ通知
1012
1050
  async function noticeQQ (comment) {
1013
1051
  if (!config.QM_SENDKEY) {
@@ -1047,12 +1085,13 @@ function getIMPushContent (comment) {
1047
1085
  async function noticeReply (currentComment) {
1048
1086
  if (!currentComment.pid) return
1049
1087
  if (!transporter) if (!await initMailer()) return
1050
- let parentComment = await db
1088
+ const parentComment = await db
1051
1089
  .collection('comment')
1052
1090
  .findOne({ _id: currentComment.pid })
1053
- parentComment = parentComment.data[0]
1054
1091
  // 回复给博主,因为会发博主通知邮件,所以不再重复通知
1055
1092
  if (config.BLOGGER_EMAIL === parentComment.mail) return
1093
+ // 回复自己的评论,不邮件通知
1094
+ if (currentComment.mail === parentComment.mail) return
1056
1095
  const PARENT_NICK = parentComment.nick
1057
1096
  const SITE_NAME = config.SITE_NAME
1058
1097
  const NICK = currentComment.nick
@@ -1116,7 +1155,7 @@ function appendHashToUrl (url, hash) {
1116
1155
  async function parse (comment) {
1117
1156
  const timestamp = Date.now()
1118
1157
  const isAdminUser = await isAdmin()
1119
- const isBloggerMail = comment.mail === config.BLOGGER_EMAIL
1158
+ const isBloggerMail = comment.mail && comment.mail === config.BLOGGER_EMAIL
1120
1159
  if (isBloggerMail && !isAdminUser) throw new Error('请先登录管理面板,再使用博主身份发送评论')
1121
1160
  const commentDo = {
1122
1161
  _id: uuidv4().replace(/-/g, ''),
@@ -1390,6 +1429,31 @@ async function getRecentComments (event) {
1390
1429
  return res
1391
1430
  }
1392
1431
 
1432
+ async function emailTest (event) {
1433
+ const res = {}
1434
+ const isAdminUser = await isAdmin()
1435
+ if (isAdminUser) {
1436
+ try {
1437
+ if (!transporter) {
1438
+ await initMailer({ throwErr: true })
1439
+ }
1440
+ const sendResult = await transporter.sendMail({
1441
+ from: config.SENDER_EMAIL,
1442
+ to: event.mail || config.BLOGGER_EMAIL || config.SENDER_EMAIL,
1443
+ subject: 'Twikoo 邮件通知测试邮件',
1444
+ html: '如果您收到这封邮件,说明 Twikoo 邮件功能配置正确'
1445
+ })
1446
+ res.result = sendResult
1447
+ } catch (e) {
1448
+ res.message = e.message
1449
+ }
1450
+ } else {
1451
+ res.code = RES_CODE.NEED_LOGIN
1452
+ res.message = '请先登录'
1453
+ }
1454
+ return res
1455
+ }
1456
+
1393
1457
  function getAvatar (comment) {
1394
1458
  if (comment.avatar) {
1395
1459
  return comment.avatar
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twikoo-vercel",
3
- "version": "1.4.3",
3
+ "version": "1.4.7",
4
4
  "description": "A simple comment system based on Tencent CloudBase (tcb).",
5
5
  "author": "imaegoo <hello@imaegoo.com> (https://github.com/imaegoo)",
6
6
  "license": "MIT",