V2EX-Comments-Summarizer

V2EX 评论区总结

目前為 2023-07-11 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name V2EX-Comments-Summarizer
  3. // @namespace https://github.com/banbri
  4. // @version 1.0
  5. // @description V2EX 评论区总结
  6. // @author Banbri
  7. // @match https://www.v2ex.com/t/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=v2ex.com
  9. // @license GPL-2.0-only
  10. // ==/UserScript==
  11.  
  12. const rightbar = document.getElementById('Rightbar')
  13.  
  14. const box = document.createElement('div')
  15. box.className = 'box'
  16. box.style.minHeight = '200px'
  17. box.style.padding = '10px'
  18. box.style.overflowX = 'hidden'
  19. rightbar.appendChild(box)
  20.  
  21. // 向 box 中添加一个 title 为 '评论区总结',并且添加样式
  22. const title = document.createElement('div')
  23. title.innerText = '评论区总结:'
  24. title.style.textAlign = 'left'
  25. title.style.fontWeight = 'bold'
  26. box.appendChild(title)
  27.  
  28. // 再新建一个 div,用于存放评论区总结的内容
  29. const contentDiv = document.createElement('div')
  30. contentDiv.className = 'reply_content'
  31. contentDiv.style.textAlign = 'left'
  32. box.appendChild(contentDiv)
  33.  
  34. // 获取到所有的评论
  35. const comments = document.querySelectorAll('.reply_content')
  36. let contentText = 'Generating...'
  37. for (let i = 0; i < comments.length; i++) {
  38. contentText += comments[i].innerText
  39. }
  40.  
  41. // 如果评论内容低于 200 个字符,就不进行总结
  42. if (contentText.length < 200) {
  43. contentDiv.innerText = '评论内容太少,不进行总结。'
  44. } else {
  45. if (contentText.length > 2000) {
  46. contentText = contentText.substring(0, 2000)
  47. }
  48. getSummary()
  49. }
  50.  
  51. async function getSummary() {
  52. const param = {
  53. model: 'gpt-3.5-turbo',
  54. temperature: 1,
  55. top_p: 0.9,
  56. frequency_penalty: 0,
  57. presence_penalty: 0,
  58. stop: '',
  59. messages: [
  60. { role: 'assistant', content: contentText },
  61. {
  62. role: 'user',
  63. content: '这是一个帖子的评论区,请总结一下,仅回复总结内容。',
  64. },
  65. ],
  66. stream: true,
  67. }
  68. const response = await fetch('https://thread-sum.com/v1/chat/completions', {
  69. method: 'POST',
  70. body: JSON.stringify(param),
  71. })
  72. const reader = response.body.getReader()
  73. const decoder = new TextDecoder('utf-8')
  74. contentText.innerText = ''
  75. let text = ''
  76. while (true) {
  77. const { done, value } = await reader.read()
  78. if (done) {
  79. break
  80. }
  81. // Massage and parse the chunk of data
  82. const chunk = decoder.decode(value, { stream: true })
  83. const dataStrList = chunk.split('\n\n')
  84. // eslint-disable-next-line
  85. dataStrList.forEach((dataStr) => {
  86. const dataJson = dataStr.replace(/^data:/, '').trim()
  87. try {
  88. const data = JSON.parse(dataJson)
  89. const content = data?.choices[0]?.delta?.content
  90. if (!content) return
  91. text += content
  92. contentDiv.innerText = text
  93. } catch (e) {}
  94. })
  95. }
  96. }

QingJ © 2025

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