V2EX-Comments-Summarizer

V2EX 评论区总结

  1. // ==UserScript==
  2. // @name V2EX-Comments-Summarizer
  3. // @namespace https://github.com/banbri
  4. // @version 1.2
  5. // @description V2EX 评论区总结
  6. // @author Banbri
  7. // @match https://*.v2ex.com/t/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=v2ex.com
  9. // @license GPL-2.0-only
  10. // @resource iconLib https://at.alicdn.com/t/c/font_3236038_ha9rkafjvq.css
  11. // @grant GM_addStyle
  12. // @grant GM_getResourceText
  13. // ==/UserScript==
  14.  
  15. GM_addStyle(GM_getResourceText('iconLib'))
  16.  
  17. const rightbar = document.getElementById('Rightbar')
  18.  
  19. const box = document.createElement('div')
  20. box.className = 'box'
  21. box.style.minHeight = '200px'
  22. box.style.padding = '10px'
  23. box.style.overflowX = 'hidden'
  24. rightbar.appendChild(box)
  25.  
  26. // 创建一个 div,用于存放标题
  27. const commentHeader = document.createElement('div')
  28. commentHeader.style.display = 'flex'
  29. commentHeader.style.justifyContent = 'space-between'
  30.  
  31. // 向 box 中添加一个 title 为 '评论区总结',并且添加样式
  32. const title = document.createElement('div')
  33. title.innerText = '评论区总结:'
  34. title.style.textAlign = 'left'
  35. title.style.fontWeight = 'bold'
  36. commentHeader.appendChild(title)
  37.  
  38. // 向 box 中添加一个icon,icon-bx-donate-heart
  39. const icon = document.createElement('i')
  40. icon.className = 'iconfont icon-bx-donate-heart'
  41. icon.style.fontSize = '20px'
  42. icon.style.color = '#E24242'
  43. icon.style.cursor = 'pointer'
  44. commentHeader.appendChild(icon)
  45. box.appendChild(commentHeader)
  46.  
  47. // 再新建一个 div,用于存放评论区总结的内容
  48. const contentDiv = document.createElement('div')
  49. contentDiv.className = 'reply_content'
  50. contentDiv.style.textAlign = 'left'
  51. box.appendChild(contentDiv)
  52.  
  53. // 创建一个 dialog,用于展示支付宝和微信收款码
  54. const dialog = document.createElement('dialog')
  55. dialog.style.width = '600px'
  56. dialog.style.height = '400px'
  57. dialog.style.borderRadius = '10px'
  58. dialog.style.boxShadow = '0 0 10px #ccc'
  59. dialog.style.padding = '10px'
  60. dialog.style.textAlign = 'center'
  61. dialog.style.position = 'fixed'
  62. dialog.style.top = '50%'
  63. dialog.style.left = '50%'
  64. dialog.style.transform = 'translate(-50%, -50%)'
  65. dialog.style.zIndex = '9999'
  66. dialog.style.background = '#fff'
  67. dialog.style.display = 'none'
  68. document.body.appendChild(dialog)
  69.  
  70. // 创建一个 img,用于展示支付宝收款码
  71. const alipay = document.createElement('img')
  72. alipay.src = 'http://lskypro.banbri.cn/i/2023/07/11/64ad66414792a.jpg'
  73. alipay.style.width = '500px'
  74. alipay.style.height = '295px'
  75. dialog.appendChild(alipay)
  76.  
  77. // 创建一个 div,用于存放支付宝和微信收款码的文字说明
  78. const text = document.createElement('div')
  79. text.innerText = '如果觉得有帮助,可以请我喝杯咖啡。'
  80. text.style.marginTop = '20px'
  81. dialog.appendChild(text)
  82.  
  83. // dialog 右上角添加一个关闭按钮
  84. const closeBtn = document.createElement('button')
  85. closeBtn.innerText = '关闭'
  86. closeBtn.style.marginTop = '20px'
  87. closeBtn.style.padding = '5px 10px'
  88. closeBtn.style.borderRadius = '5px'
  89. closeBtn.style.border = 'none'
  90. closeBtn.style.background = '#E24242'
  91. closeBtn.style.color = '#fff'
  92. closeBtn.style.cursor = 'pointer'
  93. dialog.appendChild(closeBtn)
  94.  
  95. // 点击关闭按钮,关闭 dialog
  96. closeBtn.onclick = () => {
  97. dialog.style.display = 'none'
  98. }
  99.  
  100. // 点击 icon,展示 dialog
  101. icon.onclick = () => {
  102. dialog.style.display = 'block'
  103. }
  104.  
  105. // 获取到所有的评论
  106. const comments = document.querySelectorAll('.reply_content')
  107. let contentText = ''
  108. for (let i = 0; i < comments.length; i++) {
  109. contentText += comments[i].innerText
  110. }
  111.  
  112. // 如果评论内容低于 200 个字符,就不进行总结
  113. if (contentText.length < 200) {
  114. contentDiv.innerText = '评论内容太少,不进行总结。'
  115. } else {
  116. if (contentText.length > 2000) {
  117. contentText = contentText.substring(0, 2000)
  118. }
  119. getSummary()
  120. }
  121.  
  122. async function getSummary() {
  123. const param = {
  124. model: 'gpt-3.5-turbo',
  125. temperature: 1,
  126. top_p: 0.9,
  127. frequency_penalty: 0,
  128. presence_penalty: 0,
  129. stop: '',
  130. messages: [
  131. { role: 'assistant', content: contentText },
  132. {
  133. role: 'user',
  134. content: '这是一个帖子的评论区,请总结一下,仅回复总结内容。',
  135. },
  136. ],
  137. stream: true,
  138. }
  139. const response = await fetch('https://thread-sum.com/v1/chat/completions', {
  140. method: 'POST',
  141. body: JSON.stringify(param),
  142. })
  143. const reader = response.body.getReader()
  144. const decoder = new TextDecoder('utf-8')
  145. contentText.innerText = ''
  146. let text = ''
  147. while (true) {
  148. const { done, value } = await reader.read()
  149. if (done) {
  150. break
  151. }
  152. const chunk = decoder.decode(value, { stream: true })
  153. const dataStrList = chunk.split('\n\n')
  154. dataStrList.forEach((dataStr) => {
  155. const dataJson = dataStr.replace(/^data:/, '').trim()
  156. try {
  157. const data = JSON.parse(dataJson)
  158. const content = data?.choices[0]?.delta?.content
  159. if (!content) return
  160. text += content
  161. contentDiv.innerText = text
  162. } catch (e) {}
  163. })
  164. }
  165. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址