main.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. const { WechatyBuilder } = require("wechaty")
  2. const { getGPTMessage } = require('../API/ChatGPT')
  3. const { getXunfeiMessage } = require('../API/xunfei')
  4. const sqlite3 = require('sqlite3')
  5. //sqlite数据库路径
  6. let sqliteDbPath = "./db/data.db"
  7. //打开数据库
  8. let db = new sqlite3.Database(sqliteDbPath)
  9. const wechaty = WechatyBuilder.build()
  10. function getConfigValue(configName) {
  11. return new Promise((resolve, reject) => {
  12. const query = 'SELECT value FROM wxconfig WHERE config = ?'
  13. db.get(query, [configName], (err, row) => {
  14. if (err) {
  15. reject(err)
  16. } else {
  17. const configValue = row ? row.value : null
  18. // 处理字符串 'null',如果是 'null' 则返回 null
  19. resolve(configValue === 'null' ? null : configValue)
  20. }
  21. })
  22. })
  23. }
  24. // 读取配置信息并设置相应的变量
  25. async function loadConfigValues() {
  26. try {
  27. autoReplySingle = await getConfigValue('autoReplySingle') === 'true'
  28. prefix = await getConfigValue('prefix')
  29. suffix = await getConfigValue('suffix')
  30. usemodel = await getConfigValue('usemodel')
  31. whiteRoomString = await getConfigValue('whiteRoom')
  32. keyWordsString = await getConfigValue('keyWords')
  33. blackNameString = await getConfigValue('blackName')
  34. atReply = await getConfigValue('atReply') === 'true'
  35. // 处理转义符
  36. suffix = suffix !== null ? suffix.replace(/\\n/g, '\n') : ''
  37. prefix = prefix !== null ? prefix.replace(/\\n/g, '\n') : ''
  38. // 处理用逗号分隔的字符串形式的数组
  39. whiteRoom = whiteRoomString !== null ? whiteRoomString.split(",").map(item => item.trim()) : []
  40. keyWords = keyWordsString !== null ? keyWordsString.split(",").map(item => item.trim()) : []
  41. blackName = blackNameString !== null ? blackNameString.split(",").map(item => item.trim()) : []
  42. } catch (error) {
  43. console.error('Error loading config values:', error)
  44. }
  45. }
  46. // 调用函数加载配置信息
  47. loadConfigValues()
  48. //选择模型
  49. async function sendMessageToAPI(message) {
  50. if (usemodel==='xunfei'){
  51. const content = await getXunfeiMessage(message)
  52. return content
  53. } else {
  54. const content = await getGPTMessage(message)
  55. return content
  56. }
  57. }
  58. //获取时间
  59. function getCurrentTime() {
  60. const options = {
  61. year: 'numeric',
  62. month: '2-digit',
  63. day: '2-digit',
  64. hour: '2-digit',
  65. minute: '2-digit',
  66. second: '2-digit',
  67. }
  68. const currentTime = new Date().toLocaleString('zh-CN', options)
  69. return currentTime
  70. }
  71. //停止函数运行
  72. let isRunning = false
  73. async function stopWx() {
  74. if (isRunning) {
  75. isRunning = false
  76. await wechaty.stop()
  77. Status.status = 0
  78. }
  79. }
  80. let Status = { status: null }
  81. let User = {name: null}
  82. async function wxlogin() {
  83. if (isRunning) {
  84. isRunning = false
  85. await wechaty.stop()
  86. Status.status = 0
  87. }
  88. isRunning = true
  89. return new Promise((resolve, reject) => {
  90. let qrcodeUrl
  91. // 解除之前绑定的所有事件处理程序
  92. wechaty.removeAllListeners()
  93. wechaty
  94. .on('scan', (qrcode, status) => {
  95. qrcodeUrl = `https://my.tv.sohu.com/user/a/wvideo/getQRCode.do?text=${encodeURIComponent(qrcode)}`
  96. Status.status = status
  97. // 将 qrcodeUrl 提前返回
  98. resolve(qrcodeUrl)
  99. })
  100. .on('login', async (user) => {
  101. Status.status = 200
  102. // 获取登录用户的信息
  103. const contact = await wechaty.Contact.find({ id: user.id })
  104. const name = await contact.name()
  105. const avatarFileBox = await contact.avatar()
  106. User.name = name
  107. // 将头像保存到本地
  108. const avatarFilePath = `./wechat/avatar/avatar.jpg`
  109. await avatarFileBox.toFile(avatarFilePath,true)
  110. // 有程序运行后配置未加载的问题,这里重新加载一遍
  111. loadConfigValues()
  112. })
  113. .on('logout', async () => {
  114. Status.status = null
  115. isRunning = false
  116. await wechaty.stop()
  117. })
  118. .on('message',async (message) => {
  119. if (message.self()) {
  120. return
  121. } else {
  122. if (message.type() === wechaty.Message.Type.Text) {
  123. const content = message.text()
  124. const room = message.room()
  125. const talker = message.talker()
  126. const talkername = message.talker().payload.name
  127. const foundWords = keyWords.filter(word => content.includes(word))
  128. if (room) {
  129. const roomname = message.room().payload.topic
  130. if (whiteRoom.length === 0 || whiteRoom.includes(roomname)) {
  131. //在群聊中被@
  132. if (await message.mentionSelf()) {
  133. console.log('机器人被@')
  134. if (atReply) {
  135. const apiMessage = await sendMessageToAPI(content)
  136. const senmsg = '@' + talkername + ' ' + prefix + apiMessage + suffix
  137. room.say(senmsg)
  138. //写入数据库
  139. writeToDatabase({
  140. time: getCurrentTime(),
  141. type: '群聊',
  142. recmsg: content,
  143. senmsg: senmsg,
  144. name: talkername,
  145. roomname: roomname,
  146. })
  147. return
  148. }
  149. } else if (foundWords.length > 0) {
  150. console.log('发现关键字')
  151. const apiMessage = await sendMessageToAPI(content)
  152. const senmsg = '@' + talkername + ' ' + prefix + apiMessage + suffix
  153. room.say(senmsg)
  154. //写入数据库
  155. writeToDatabase({
  156. time: getCurrentTime(),
  157. type: '群聊',
  158. recmsg: content,
  159. senmsg: senmsg,
  160. name: talkername,
  161. roomname: roomname,
  162. })
  163. return
  164. }
  165. } else {
  166. return
  167. }
  168. } else {
  169. if (autoReplySingle) {
  170. if (blackName.includes(talkername)) {
  171. return
  172. } else {
  173. const apiMessage = await sendMessageToAPI(content)
  174. const senmsg = prefix + apiMessage + suffix
  175. talker.say(senmsg)
  176. writeToDatabase({
  177. time: getCurrentTime(),
  178. type: '私聊',
  179. recmsg: content,
  180. senmsg: senmsg,
  181. name: message.talker().payload.name,
  182. roomname: null,
  183. })
  184. return
  185. }
  186. }
  187. }
  188. } else {
  189. return
  190. }
  191. }
  192. }
  193. )
  194. wechaty.start()
  195. wechaty.on('error', (error) => {
  196. reject(error)
  197. })
  198. })
  199. }
  200. //向数据库写入数据
  201. function writeToDatabase(data) {
  202. const { time, type, recmsg, senmsg, name, roomname } = data
  203. const insertQuery = `INSERT INTO message (time, type, recmsg, senmsg, name, roomname) VALUES (?, ?, ?, ?, ?, ?)`
  204. db.run(insertQuery, [time, type, recmsg, senmsg, name, roomname], (error) => {
  205. if (error) {
  206. console.error('数据库写入失败:', error)
  207. }
  208. })
  209. }
  210. // 更新设置到数据库
  211. function updateConfigValue(configName, configValue) {
  212. const query = 'INSERT OR REPLACE INTO wxconfig (config, value) VALUES (?, ?)'
  213. db.run(query, [configName, configValue], (err) => {
  214. if (err) {
  215. console.error('数据库写入失败:', err)
  216. }
  217. })
  218. }
  219. function setWx(key,value) {
  220. updateConfigValue(key,value)
  221. }
  222. module.exports = {
  223. wxlogin,
  224. Status,
  225. setWx,
  226. stopWx,
  227. loadConfigValues,
  228. User
  229. }